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 (void)setRepr(binder, getLocalLevel(), REPR_NONE);
74 }
75
getLocalLevel()76 Stability::Level Stability::getLocalLevel() {
77 #ifdef __ANDROID_APEX__
78 #error APEX can't use libbinder (must use libbinder_ndk)
79 #endif
80
81 #ifdef __ANDROID_VNDK__
82 return Level::VENDOR;
83 #else
84 // TODO(b/139325195): split up stability levels for system/APEX.
85 return Level::SYSTEM;
86 #endif
87 }
88
89 status_t Stability::setRepr(IBinder* binder, int32_t setting, uint32_t flags) {
90 bool log = flags & REPR_LOG;
91 bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE;
92
93 int16_t current = getRepr(binder);
94
95 // null binder is always written w/ 'UNDECLARED' stability
96 if (binder == nullptr) {
97 if (setting == UNDECLARED) {
98 return OK;
99 } else {
100 if (log) {
101 ALOGE("Null binder written with stability %s.", levelString(setting).c_str());
102 }
103 return BAD_TYPE;
104 }
105 }
106
107 if (!isDeclaredLevel(setting)) {
108 if (log) {
109 ALOGE("Can only set known stability, not %d.", setting);
110 }
111 return BAD_TYPE;
112 }
113 Level levelSetting = static_cast<Level>(setting);
114
115 if (current == setting) return OK;
116
117 bool hasAlreadyBeenSet = current != Level::UNDECLARED;
118 bool isAllowedDowngrade = allowDowngrade && check(current, levelSetting);
119 if (hasAlreadyBeenSet && !isAllowedDowngrade) {
120 if (log) {
121 ALOGE("Interface being set with %s but it is already marked as %s",
122 levelString(setting).c_str(), levelString(current).c_str());
123 }
124 return BAD_TYPE;
125 }
126
127 if (isAllowedDowngrade) {
128 ALOGI("Interface set with %s downgraded to %s stability", levelString(current).c_str(),
129 levelString(setting).c_str());
130 }
131
132 BBinder* local = binder->localBinder();
133 if (local != nullptr) {
134 local->mStability = setting;
135 } else {
136 binder->remoteBinder()->mStability = setting;
137 }
138
139 return OK;
140 }
141
142 int16_t Stability::getRepr(IBinder* binder) {
143 if (binder == nullptr) {
144 return Level::UNDECLARED;
145 }
146
147 BBinder* local = binder->localBinder();
148 if (local != nullptr) {
149 return local->mStability;
150 }
151
152 return binder->remoteBinder()->mStability;
153 }
154
155 bool Stability::check(int16_t provided, Level required) {
156 bool stable = (provided & required) == required;
157
158 if (provided != UNDECLARED && !isDeclaredLevel(provided)) {
159 ALOGE("Unknown stability when checking interface stability %d.", provided);
160
161 stable = false;
162 }
163
164 return stable;
165 }
166
167 bool Stability::isDeclaredLevel(int32_t stability) {
168 return stability == VENDOR || stability == SYSTEM || stability == VINTF;
169 }
170
171 std::string Stability::levelString(int32_t level) {
172 switch (level) {
173 case Level::UNDECLARED: return "undeclared stability";
174 case Level::VENDOR: return "vendor stability";
175 case Level::SYSTEM: return "system stability";
176 case Level::VINTF: return "vintf stability";
177 }
178 return "unknown stability " + std::to_string(level);
179 }
180
181 } // namespace internal
182 } // namespace stability
183