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