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