Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c8b582fc authored by Steven Moreland's avatar Steven Moreland Committed by Automerger Merge Worker
Browse files

Merge "libbinder: allow stability downgrade" am: 7f284f96 am: 54d423cd

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1649815

Change-Id: I47f0ce01cff6d6a0406798b5cc2b0c9bb907ac0d
parents 280bc1fc 54d423cd
Loading
Loading
Loading
Loading
+30 −7
Original line number Original line Diff line number Diff line
@@ -38,6 +38,18 @@ Stability::Category Stability::Category::currentFromLevel(Level level) {
    };
    };
}
}


void Stability::forceDowngradeCompilationUnit(const sp<IBinder>& binder) {
    // Downgrading a remote binder would require also copying the version from
    // the binder sent here. In practice though, we don't need to downgrade the
    // stability of a remote binder, since this would as an effect only restrict
    // what we can do to it.
    LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");

    auto stability = Category::currentFromLevel(getLocalLevel());
    status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE);
    LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
}

std::string Stability::Category::debugString() {
std::string Stability::Category::debugString() {
    return levelString(level) + " wire protocol version "
    return levelString(level) + " wire protocol version "
        + std::to_string(version);
        + std::to_string(version);
@@ -45,13 +57,13 @@ std::string Stability::Category::debugString() {


void Stability::markCompilationUnit(IBinder* binder) {
void Stability::markCompilationUnit(IBinder* binder) {
    auto stability = Category::currentFromLevel(getLocalLevel());
    auto stability = Category::currentFromLevel(getLocalLevel());
    status_t result = setRepr(binder, stability.repr(), true /*log*/);
    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
    LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
    LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
}
}


void Stability::markVintf(IBinder* binder) {
void Stability::markVintf(IBinder* binder) {
    auto stability = Category::currentFromLevel(Level::VINTF);
    auto stability = Category::currentFromLevel(Level::VINTF);
    status_t result = setRepr(binder, stability.repr(), true /*log*/);
    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
    LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
    LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
}
}


@@ -62,7 +74,7 @@ void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& bin


void Stability::markVndk(IBinder* binder) {
void Stability::markVndk(IBinder* binder) {
    auto stability = Category::currentFromLevel(Level::VENDOR);
    auto stability = Category::currentFromLevel(Level::VENDOR);
    status_t result = setRepr(binder, stability.repr(), true /*log*/);
    status_t result = setRepr(binder, stability.repr(), REPR_LOG);
    LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
    LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
}
}


@@ -72,7 +84,7 @@ bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {


void Stability::tryMarkCompilationUnit(IBinder* binder) {
void Stability::tryMarkCompilationUnit(IBinder* binder) {
    auto stability = Category::currentFromLevel(getLocalLevel());
    auto stability = Category::currentFromLevel(getLocalLevel());
    (void) setRepr(binder, stability.repr(), false /*log*/);
    (void) setRepr(binder, stability.repr(), REPR_NONE);
}
}


Stability::Level Stability::getLocalLevel() {
Stability::Level Stability::getLocalLevel() {
@@ -94,7 +106,10 @@ Stability::Level Stability::getLocalLevel() {
#endif
#endif
}
}


status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) {
status_t Stability::setRepr(IBinder* binder, int32_t representation, uint32_t flags) {
    bool log = flags & REPR_LOG;
    bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE;

    auto current = getCategory(binder);
    auto current = getCategory(binder);
    auto setting = Category::fromRepr(representation);
    auto setting = Category::fromRepr(representation);


@@ -129,7 +144,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) {
        return BAD_TYPE;
        return BAD_TYPE;
    }
    }


    if (current.repr() != 0 && current != setting) {
    if (current == setting) return OK;

    bool hasAlreadyBeenSet = current.repr() != 0;
    bool isAllowedDowngrade = allowDowngrade && check(current, setting.level);
    if (hasAlreadyBeenSet && !isAllowedDowngrade) {
        if (log) {
        if (log) {
            ALOGE("Interface being set with %s but it is already marked as %s",
            ALOGE("Interface being set with %s but it is already marked as %s",
                  setting.debugString().c_str(),
                  setting.debugString().c_str(),
@@ -138,7 +157,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) {
        return BAD_TYPE;
        return BAD_TYPE;
    }
    }


    if (current == setting) return OK;
    if (isAllowedDowngrade) {
        ALOGI("Interface set with %s downgraded to %s stability",
              current.debugString().c_str(),
              setting.debugString().c_str());
    }


    BBinder* local = binder->localBinder();
    BBinder* local = binder->localBinder();
    if (local != nullptr) {
    if (local != nullptr) {
+15 −3
Original line number Original line Diff line number Diff line
@@ -49,10 +49,17 @@ namespace internal {
// that it knows how to process. The summary of stability of a binder is
// that it knows how to process. The summary of stability of a binder is
// represented by a Stability::Category object.
// represented by a Stability::Category object.


// WARNING: These APIs are only ever expected to be called by auto-generated code.
//     Instead of calling them, you should set the stability of a .aidl interface
class Stability final {
class Stability final {
public:
public:
    // Given a binder interface at a certain stability, there may be some
    // requirements associated with that higher stability level. For instance, a
    // VINTF stability binder is required to be in the VINTF manifest. This API
    // can be called to use that same interface within a partition.
    static void forceDowngradeCompilationUnit(const sp<IBinder>& binder);

    // WARNING: Below APIs are only ever expected to be called by auto-generated code.
    //     Instead of calling them, you should set the stability of a .aidl interface

    // WARNING: This is only ever expected to be called by auto-generated code. You likely want to
    // WARNING: This is only ever expected to be called by auto-generated code. You likely want to
    // change or modify the stability class of the interface you are using.
    // change or modify the stability class of the interface you are using.
    // This must be called as soon as the binder in question is constructed. No thread safety
    // This must be called as soon as the binder in question is constructed. No thread safety
@@ -139,9 +146,14 @@ private:
    // returns the stability according to how this was built
    // returns the stability according to how this was built
    static Level getLocalLevel();
    static Level getLocalLevel();


    enum {
      REPR_NONE = 0,
      REPR_LOG = 1,
      REPR_ALLOW_DOWNGRADE = 2,
    };
    // applies stability to binder if stability level is known
    // applies stability to binder if stability level is known
    __attribute__((warn_unused_result))
    __attribute__((warn_unused_result))
    static status_t setRepr(IBinder* binder, int32_t representation, bool log);
    static status_t setRepr(IBinder* binder, int32_t representation, uint32_t flags);


    // get stability information as encoded on the wire
    // get stability information as encoded on the wire
    static Category getCategory(IBinder* binder);
    static Category getCategory(IBinder* binder);
+11 −0
Original line number Original line Diff line number Diff line
@@ -131,6 +131,17 @@ TEST(BinderStability, OnlyVintfStabilityBinderNeedsVintfDeclaration) {
    EXPECT_TRUE(Stability::requiresVintfDeclaration(BadStableBinder::vintf()));
    EXPECT_TRUE(Stability::requiresVintfDeclaration(BadStableBinder::vintf()));
}
}


TEST(BinderStability, ForceDowngradeStability) {
    sp<IBinder> someBinder = BadStableBinder::vintf();

    EXPECT_TRUE(Stability::requiresVintfDeclaration(someBinder));

    // silly to do this after already using the binder, but it's for the test
    Stability::forceDowngradeCompilationUnit(someBinder);

    EXPECT_FALSE(Stability::requiresVintfDeclaration(someBinder));
}

TEST(BinderStability, VintfStabilityServerMustBeDeclaredInManifest) {
TEST(BinderStability, VintfStabilityServerMustBeDeclaredInManifest) {
    sp<IBinder> vintfServer = BadStableBinder::vintf();
    sp<IBinder> vintfServer = BadStableBinder::vintf();