| /* |
| * Copyright (C) 2019 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #pragma once |
| |
| #include <binder/IBinder.h> |
| #include <string> |
| |
| namespace android { |
| |
| class BpBinder; |
| class ProcessState; |
| |
| namespace internal { |
| |
| // Stability encodes how a binder changes over time. There are two levels of |
| // stability: |
| // 1). the interface stability - this is how a particular set of API calls (a |
| // particular ordering of things like writeInt32/readInt32) are changed over |
| // time. If one release, we have 'writeInt32' and the next release, we have |
| // 'writeInt64', then this interface doesn't have a very stable |
| // Stability::Level. Usually this ordering is controlled by a .aidl file. |
| // 2). the wire format stability - this is how these API calls map to actual |
| // bytes that are written to the wire (literally, this is how they are written |
| // to the kernel inside of IBinder::transact, but it may be expanded to other |
| // wires in the future). For instance, writeInt32 in binder translates to |
| // writing a 4-byte little-endian integer in two's complement. You can imagine |
| // in the future, we change writeInt32/readInt32 to instead write 8-bytes with |
| // that integer and some check bits. In this case, the wire format changes, |
| // but as long as a client libbinder knows to keep on writing a 4-byte value |
| // to old servers, and new servers know how to interpret the 8-byte result, |
| // they can still communicate. |
| // |
| // This class is specifically about (1). (2) is not currently tracked by |
| // libbinder for regular binder calls, and everything on the system uses the |
| // same copy of libbinder. |
| |
| 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 the local partition. |
| static void forceDowngradeToLocalStability(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: The only client of |
| // - forceDowngradeToSystemStability() and; |
| // - korceDowngradeToVendorStability() |
| // should be AIBinder_forceDowngradeToLocalStability(). |
| // |
| // getLocalLevel() in libbinder returns Level::SYSTEM when called |
| // from libbinder_ndk (even on vendor partition). So we explicitly provide |
| // these methods for use by the NDK API: |
| // AIBinder_forceDowngradeToLocalStability(). |
| // |
| // This allows correctly downgrading the binder's stability to either system/vendor, |
| // depending on the partition. |
| |
| // 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 the vendor partition. |
| static void forceDowngradeToVendorStability(const sp<IBinder>& binder); |
| |
| // 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 the system partition. |
| static void forceDowngradeToSystemStability(const sp<IBinder>& binder); |
| |
| // 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 |
| // is provided. |
| // E.g. stability is according to libbinder compilation unit |
| static void markCompilationUnit(IBinder* binder); |
| // 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 |
| // is provided. |
| // E.g. stability is according to libbinder_ndk or Java SDK AND the interface |
| // expressed here is guaranteed to be stable for multiple years (Stable AIDL) |
| static void markVintf(IBinder* binder); |
| |
| // WARNING: for debugging only |
| static std::string debugToString(const sp<IBinder>& binder); |
| |
| // WARNING: This is only ever expected to be called by auto-generated code or tests. |
| // You likely want to change or modify the stability of the interface you are using. |
| // This must be called as soon as the binder in question is constructed. No thread safety |
| // is provided. |
| // E.g. stability is according to libbinder_ndk or Java SDK AND the interface |
| // expressed here is guaranteed to be stable for multiple years (Stable AIDL) |
| // If this is called when __ANDROID_VNDK__ is not defined, then it is UB and will likely |
| // break the device during GSI or other tests. |
| static void markVndk(IBinder* binder); |
| |
| // Returns true if the binder needs to be declared in the VINTF manifest or |
| // else false if the binder is local to the current partition. |
| static bool requiresVintfDeclaration(const sp<IBinder>& binder); |
| private: |
| // Parcel needs to read/write stability level in an unstable format. |
| friend ::android::Parcel; |
| |
| // only expose internal APIs inside of libbinder, for checking stability |
| friend ::android::BpBinder; |
| |
| // so that it can mark the context object (only the root object doesn't go |
| // through Parcel) |
| friend ::android::ProcessState; |
| |
| static void tryMarkCompilationUnit(IBinder* binder); |
| |
| // Currently, we use int16_t for Level so that it can fit in BBinder. |
| // However, on the wire, we have 4 bytes reserved for stability, so whenever |
| // we ingest a Level, we always accept an int32_t. |
| enum Level : int16_t { |
| UNDECLARED = 0, |
| |
| VENDOR = 0b000011, |
| SYSTEM = 0b001100, |
| VINTF = 0b111111, |
| }; |
| |
| // returns the stability according to how this was built |
| static Level getLocalLevel(); |
| |
| // Downgrades binder stability to the specified level. |
| static void forceDowngradeToStability(const sp<IBinder>& binder, Level level); |
| |
| 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 setting, |
| uint32_t flags); |
| |
| // get stability information as encoded on the wire |
| static int16_t getRepr(IBinder* binder); |
| |
| // whether a transaction on binder is allowed, if the transaction |
| // is done from a context with a specific stability level |
| static bool check(int16_t provided, Level required); |
| |
| static bool isDeclaredLevel(int32_t level); |
| static std::string levelString(int32_t level); |
| |
| Stability(); |
| }; |
| |
| } // namespace internal |
| } // namespace android |