xref: /aosp_15_r20/frameworks/native/libs/binder/Stability.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "Stability"
17*38e8c45fSAndroid Build Coastguard Worker 
18*38e8c45fSAndroid Build Coastguard Worker #include <binder/Stability.h>
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #include <binder/BpBinder.h>
21*38e8c45fSAndroid Build Coastguard Worker #include <binder/Binder.h>
22*38e8c45fSAndroid Build Coastguard Worker 
23*38e8c45fSAndroid Build Coastguard Worker namespace android {
24*38e8c45fSAndroid Build Coastguard Worker namespace internal {
25*38e8c45fSAndroid Build Coastguard Worker 
forceDowngradeToStability(const sp<IBinder> & binder,Level level)26*38e8c45fSAndroid Build Coastguard Worker void Stability::forceDowngradeToStability(const sp<IBinder>& binder, Level level) {
27*38e8c45fSAndroid Build Coastguard Worker     // Downgrading a remote binder would require also copying the version from
28*38e8c45fSAndroid Build Coastguard Worker     // the binder sent here. In practice though, we don't need to downgrade the
29*38e8c45fSAndroid Build Coastguard Worker     // stability of a remote binder, since this would as an effect only restrict
30*38e8c45fSAndroid Build Coastguard Worker     // what we can do to it.
31*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");
32*38e8c45fSAndroid Build Coastguard Worker 
33*38e8c45fSAndroid Build Coastguard Worker     status_t result = setRepr(binder.get(), level, REPR_LOG | REPR_ALLOW_DOWNGRADE);
34*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
35*38e8c45fSAndroid Build Coastguard Worker }
36*38e8c45fSAndroid Build Coastguard Worker 
forceDowngradeToLocalStability(const sp<IBinder> & binder)37*38e8c45fSAndroid Build Coastguard Worker void Stability::forceDowngradeToLocalStability(const sp<IBinder>& binder) {
38*38e8c45fSAndroid Build Coastguard Worker     forceDowngradeToStability(binder, getLocalLevel());
39*38e8c45fSAndroid Build Coastguard Worker }
40*38e8c45fSAndroid Build Coastguard Worker 
forceDowngradeToSystemStability(const sp<IBinder> & binder)41*38e8c45fSAndroid Build Coastguard Worker void Stability::forceDowngradeToSystemStability(const sp<IBinder>& binder) {
42*38e8c45fSAndroid Build Coastguard Worker     forceDowngradeToStability(binder, Level::SYSTEM);
43*38e8c45fSAndroid Build Coastguard Worker }
44*38e8c45fSAndroid Build Coastguard Worker 
forceDowngradeToVendorStability(const sp<IBinder> & binder)45*38e8c45fSAndroid Build Coastguard Worker void Stability::forceDowngradeToVendorStability(const sp<IBinder>& binder) {
46*38e8c45fSAndroid Build Coastguard Worker     forceDowngradeToStability(binder, Level::VENDOR);
47*38e8c45fSAndroid Build Coastguard Worker }
48*38e8c45fSAndroid Build Coastguard Worker 
markCompilationUnit(IBinder * binder)49*38e8c45fSAndroid Build Coastguard Worker void Stability::markCompilationUnit(IBinder* binder) {
50*38e8c45fSAndroid Build Coastguard Worker     status_t result = setRepr(binder, getLocalLevel(), REPR_LOG);
51*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
52*38e8c45fSAndroid Build Coastguard Worker }
53*38e8c45fSAndroid Build Coastguard Worker 
markVintf(IBinder * binder)54*38e8c45fSAndroid Build Coastguard Worker void Stability::markVintf(IBinder* binder) {
55*38e8c45fSAndroid Build Coastguard Worker     status_t result = setRepr(binder, Level::VINTF, REPR_LOG);
56*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
57*38e8c45fSAndroid Build Coastguard Worker }
58*38e8c45fSAndroid Build Coastguard Worker 
debugToString(const sp<IBinder> & binder)59*38e8c45fSAndroid Build Coastguard Worker std::string Stability::debugToString(const sp<IBinder>& binder) {
60*38e8c45fSAndroid Build Coastguard Worker     return levelString(getRepr(binder.get()));
61*38e8c45fSAndroid Build Coastguard Worker }
62*38e8c45fSAndroid Build Coastguard Worker 
markVndk(IBinder * binder)63*38e8c45fSAndroid Build Coastguard Worker void Stability::markVndk(IBinder* binder) {
64*38e8c45fSAndroid Build Coastguard Worker     status_t result = setRepr(binder, Level::VENDOR, REPR_LOG);
65*38e8c45fSAndroid Build Coastguard Worker     LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
66*38e8c45fSAndroid Build Coastguard Worker }
67*38e8c45fSAndroid Build Coastguard Worker 
requiresVintfDeclaration(const sp<IBinder> & binder)68*38e8c45fSAndroid Build Coastguard Worker bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
69*38e8c45fSAndroid Build Coastguard Worker     return check(getRepr(binder.get()), Level::VINTF);
70*38e8c45fSAndroid Build Coastguard Worker }
71*38e8c45fSAndroid Build Coastguard Worker 
tryMarkCompilationUnit(IBinder * binder)72*38e8c45fSAndroid Build Coastguard Worker void Stability::tryMarkCompilationUnit(IBinder* binder) {
73*38e8c45fSAndroid Build Coastguard Worker     std::ignore = setRepr(binder, getLocalLevel(), REPR_NONE);
74*38e8c45fSAndroid Build Coastguard Worker }
75*38e8c45fSAndroid Build Coastguard Worker 
76*38e8c45fSAndroid Build Coastguard Worker // after deprecation of the VNDK, these should be aliases. At some point
77*38e8c45fSAndroid Build Coastguard Worker // all references to __ANDROID_VNDK__ should be replaced by __ANDROID_VENDOR__
78*38e8c45fSAndroid Build Coastguard Worker // but for right now, check that this condition holds because some
79*38e8c45fSAndroid Build Coastguard Worker // places check __ANDROID_VNDK__ and some places check __ANDROID_VENDOR__
80*38e8c45fSAndroid Build Coastguard Worker #if defined(__ANDROID_VNDK__) != defined(__ANDROID_VENDOR__)
81*38e8c45fSAndroid Build Coastguard Worker #error "__ANDROID_VNDK__ and __ANDROID_VENDOR__ should be aliases"
82*38e8c45fSAndroid Build Coastguard Worker #endif
83*38e8c45fSAndroid Build Coastguard Worker 
getLocalLevel()84*38e8c45fSAndroid Build Coastguard Worker Stability::Level Stability::getLocalLevel() {
85*38e8c45fSAndroid Build Coastguard Worker #ifdef __ANDROID_APEX__
86*38e8c45fSAndroid Build Coastguard Worker #error "APEX can't use libbinder (must use libbinder_ndk)"
87*38e8c45fSAndroid Build Coastguard Worker #endif
88*38e8c45fSAndroid Build Coastguard Worker 
89*38e8c45fSAndroid Build Coastguard Worker #ifdef __ANDROID_VNDK__
90*38e8c45fSAndroid Build Coastguard Worker     return Level::VENDOR;
91*38e8c45fSAndroid Build Coastguard Worker #else
92*38e8c45fSAndroid Build Coastguard Worker     // TODO(b/139325195): split up stability levels for system/APEX.
93*38e8c45fSAndroid Build Coastguard Worker     return Level::SYSTEM;
94*38e8c45fSAndroid Build Coastguard Worker #endif
95*38e8c45fSAndroid Build Coastguard Worker }
96*38e8c45fSAndroid Build Coastguard Worker 
setRepr(IBinder * binder,int32_t setting,uint32_t flags)97*38e8c45fSAndroid Build Coastguard Worker status_t Stability::setRepr(IBinder* binder, int32_t setting, uint32_t flags) {
98*38e8c45fSAndroid Build Coastguard Worker     bool log = flags & REPR_LOG;
99*38e8c45fSAndroid Build Coastguard Worker     bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE;
100*38e8c45fSAndroid Build Coastguard Worker 
101*38e8c45fSAndroid Build Coastguard Worker     int16_t current = getRepr(binder);
102*38e8c45fSAndroid Build Coastguard Worker 
103*38e8c45fSAndroid Build Coastguard Worker     // null binder is always written w/ 'UNDECLARED' stability
104*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
105*38e8c45fSAndroid Build Coastguard Worker         if (setting == UNDECLARED) {
106*38e8c45fSAndroid Build Coastguard Worker             return OK;
107*38e8c45fSAndroid Build Coastguard Worker         } else {
108*38e8c45fSAndroid Build Coastguard Worker             if (log) {
109*38e8c45fSAndroid Build Coastguard Worker                 ALOGE("Null binder written with stability %s.", levelString(setting).c_str());
110*38e8c45fSAndroid Build Coastguard Worker             }
111*38e8c45fSAndroid Build Coastguard Worker             return BAD_TYPE;
112*38e8c45fSAndroid Build Coastguard Worker         }
113*38e8c45fSAndroid Build Coastguard Worker     }
114*38e8c45fSAndroid Build Coastguard Worker 
115*38e8c45fSAndroid Build Coastguard Worker     if (!isDeclaredLevel(setting)) {
116*38e8c45fSAndroid Build Coastguard Worker         if (log) {
117*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Can only set known stability, not %d.", setting);
118*38e8c45fSAndroid Build Coastguard Worker         }
119*38e8c45fSAndroid Build Coastguard Worker         return BAD_TYPE;
120*38e8c45fSAndroid Build Coastguard Worker     }
121*38e8c45fSAndroid Build Coastguard Worker     Level levelSetting = static_cast<Level>(setting);
122*38e8c45fSAndroid Build Coastguard Worker 
123*38e8c45fSAndroid Build Coastguard Worker     if (current == setting) return OK;
124*38e8c45fSAndroid Build Coastguard Worker 
125*38e8c45fSAndroid Build Coastguard Worker     bool hasAlreadyBeenSet = current != Level::UNDECLARED;
126*38e8c45fSAndroid Build Coastguard Worker     bool isAllowedDowngrade = allowDowngrade && check(current, levelSetting);
127*38e8c45fSAndroid Build Coastguard Worker     if (hasAlreadyBeenSet && !isAllowedDowngrade) {
128*38e8c45fSAndroid Build Coastguard Worker         if (log) {
129*38e8c45fSAndroid Build Coastguard Worker             ALOGE("Interface being set with %s but it is already marked as %s",
130*38e8c45fSAndroid Build Coastguard Worker                   levelString(setting).c_str(), levelString(current).c_str());
131*38e8c45fSAndroid Build Coastguard Worker         }
132*38e8c45fSAndroid Build Coastguard Worker         return BAD_TYPE;
133*38e8c45fSAndroid Build Coastguard Worker     }
134*38e8c45fSAndroid Build Coastguard Worker 
135*38e8c45fSAndroid Build Coastguard Worker     if (isAllowedDowngrade) {
136*38e8c45fSAndroid Build Coastguard Worker         ALOGI("Interface set with %s downgraded to %s stability", levelString(current).c_str(),
137*38e8c45fSAndroid Build Coastguard Worker               levelString(setting).c_str());
138*38e8c45fSAndroid Build Coastguard Worker     }
139*38e8c45fSAndroid Build Coastguard Worker 
140*38e8c45fSAndroid Build Coastguard Worker     BBinder* local = binder->localBinder();
141*38e8c45fSAndroid Build Coastguard Worker     if (local != nullptr) {
142*38e8c45fSAndroid Build Coastguard Worker         local->mStability = setting;
143*38e8c45fSAndroid Build Coastguard Worker     } else {
144*38e8c45fSAndroid Build Coastguard Worker         binder->remoteBinder()->mStability = setting;
145*38e8c45fSAndroid Build Coastguard Worker     }
146*38e8c45fSAndroid Build Coastguard Worker 
147*38e8c45fSAndroid Build Coastguard Worker     return OK;
148*38e8c45fSAndroid Build Coastguard Worker }
149*38e8c45fSAndroid Build Coastguard Worker 
getRepr(IBinder * binder)150*38e8c45fSAndroid Build Coastguard Worker int16_t Stability::getRepr(IBinder* binder) {
151*38e8c45fSAndroid Build Coastguard Worker     if (binder == nullptr) {
152*38e8c45fSAndroid Build Coastguard Worker         return Level::UNDECLARED;
153*38e8c45fSAndroid Build Coastguard Worker     }
154*38e8c45fSAndroid Build Coastguard Worker 
155*38e8c45fSAndroid Build Coastguard Worker     BBinder* local = binder->localBinder();
156*38e8c45fSAndroid Build Coastguard Worker     if (local != nullptr) {
157*38e8c45fSAndroid Build Coastguard Worker         return local->mStability;
158*38e8c45fSAndroid Build Coastguard Worker     }
159*38e8c45fSAndroid Build Coastguard Worker 
160*38e8c45fSAndroid Build Coastguard Worker     return binder->remoteBinder()->mStability;
161*38e8c45fSAndroid Build Coastguard Worker }
162*38e8c45fSAndroid Build Coastguard Worker 
check(int16_t provided,Level required)163*38e8c45fSAndroid Build Coastguard Worker bool Stability::check(int16_t provided, Level required) {
164*38e8c45fSAndroid Build Coastguard Worker     bool stable = (provided & required) == required;
165*38e8c45fSAndroid Build Coastguard Worker 
166*38e8c45fSAndroid Build Coastguard Worker     if (provided != UNDECLARED && !isDeclaredLevel(provided)) {
167*38e8c45fSAndroid Build Coastguard Worker         ALOGE("Unknown stability when checking interface stability %d.", provided);
168*38e8c45fSAndroid Build Coastguard Worker 
169*38e8c45fSAndroid Build Coastguard Worker         stable = false;
170*38e8c45fSAndroid Build Coastguard Worker     }
171*38e8c45fSAndroid Build Coastguard Worker 
172*38e8c45fSAndroid Build Coastguard Worker     return stable;
173*38e8c45fSAndroid Build Coastguard Worker }
174*38e8c45fSAndroid Build Coastguard Worker 
isDeclaredLevel(int32_t stability)175*38e8c45fSAndroid Build Coastguard Worker bool Stability::isDeclaredLevel(int32_t stability) {
176*38e8c45fSAndroid Build Coastguard Worker     return stability == VENDOR || stability == SYSTEM || stability == VINTF;
177*38e8c45fSAndroid Build Coastguard Worker }
178*38e8c45fSAndroid Build Coastguard Worker 
levelString(int32_t level)179*38e8c45fSAndroid Build Coastguard Worker std::string Stability::levelString(int32_t level) {
180*38e8c45fSAndroid Build Coastguard Worker     switch (level) {
181*38e8c45fSAndroid Build Coastguard Worker         case Level::UNDECLARED: return "undeclared stability";
182*38e8c45fSAndroid Build Coastguard Worker         case Level::VENDOR: return "vendor stability";
183*38e8c45fSAndroid Build Coastguard Worker         case Level::SYSTEM: return "system stability";
184*38e8c45fSAndroid Build Coastguard Worker         case Level::VINTF: return "vintf stability";
185*38e8c45fSAndroid Build Coastguard Worker     }
186*38e8c45fSAndroid Build Coastguard Worker     return "unknown stability " + std::to_string(level);
187*38e8c45fSAndroid Build Coastguard Worker }
188*38e8c45fSAndroid Build Coastguard Worker 
189*38e8c45fSAndroid Build Coastguard Worker }  // namespace internal
190*38e8c45fSAndroid Build Coastguard Worker }  // namespace stability
191