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