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

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

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

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

Change-Id: Ib59a0c6fdc3f91107857d394c0c5605f8e6e0023
parents a8f89293 c8b582fc
Loading
Loading
Loading
Loading
+30 −7
Original line number 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() {
    return levelString(level) + " wire protocol version "
        + std::to_string(version);
@@ -45,13 +57,13 @@ std::string Stability::Category::debugString() {

void Stability::markCompilationUnit(IBinder* binder) {
    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.");
}

void Stability::markVintf(IBinder* binder) {
    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.");
}

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

void Stability::markVndk(IBinder* binder) {
    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.");
}

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

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

Stability::Level Stability::getLocalLevel() {
@@ -88,7 +100,10 @@ Stability::Level Stability::getLocalLevel() {
#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 setting = Category::fromRepr(representation);

@@ -123,7 +138,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) {
        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) {
            ALOGE("Interface being set with %s but it is already marked as %s",
                  setting.debugString().c_str(),
@@ -132,7 +151,11 @@ status_t Stability::setRepr(IBinder* binder, int32_t representation, bool log) {
        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();
    if (local != nullptr) {
+15 −3
Original line number 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
// 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 {
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
    // 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
@@ -139,9 +146,14 @@ private:
    // returns the stability according to how this was built
    static Level getLocalLevel();

    enum {
      REPR_NONE = 0,
      REPR_LOG = 1,
      REPR_ALLOW_DOWNGRADE = 2,
    };
    // applies stability to binder if stability level is known
    __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
    static Category getCategory(IBinder* binder);
+11 −0
Original line number Diff line number Diff line
@@ -131,6 +131,17 @@ TEST(BinderStability, OnlyVintfStabilityBinderNeedsVintfDeclaration) {
    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) {
    sp<IBinder> vintfServer = BadStableBinder::vintf();