blob: c3f1ba7b4d7099384a2ac0e2bc6fd9db37ab5163 [file] [log] [blame]
Steven Morelanddea3cf92019-07-16 18:06:55 -07001/*
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 */
Steven Moreland89ddfc52020-11-13 02:39:26 +000016#define LOG_TAG "Stability"
17
Steven Morelanddea3cf92019-07-16 18:06:55 -070018#include <binder/Stability.h>
19
Steven Morelanda7fb0182020-02-26 16:02:08 -080020#include <binder/BpBinder.h>
21#include <binder/Binder.h>
22
Steven Morelanddea3cf92019-07-16 18:06:55 -070023namespace android {
24namespace internal {
25
Steven Moreland89ddfc52020-11-13 02:39:26 +000026// the libbinder parcel format is currently unstable
27
28// oldest version which is supported
29constexpr uint8_t kBinderWireFormatOldest = 1;
30// current version
31constexpr uint8_t kBinderWireFormatVersion = 1;
32
33Stability::Category Stability::Category::currentFromLevel(Level level) {
34 return {
35 .version = kBinderWireFormatVersion,
36 .reserved = {0},
37 .level = level,
38 };
39}
40
Steven Morelande35fef32021-03-23 01:38:24 +000041void Stability::forceDowngradeCompilationUnit(const sp<IBinder>& binder) {
42 // Downgrading a remote binder would require also copying the version from
43 // the binder sent here. In practice though, we don't need to downgrade the
44 // stability of a remote binder, since this would as an effect only restrict
45 // what we can do to it.
46 LOG_ALWAYS_FATAL_IF(!binder || !binder->localBinder(), "Can only downgrade local binder");
47
48 auto stability = Category::currentFromLevel(getLocalLevel());
49 status_t result = setRepr(binder.get(), stability.repr(), REPR_LOG | REPR_ALLOW_DOWNGRADE);
50 LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
51}
52
Steven Moreland89ddfc52020-11-13 02:39:26 +000053std::string Stability::Category::debugString() {
54 return levelString(level) + " wire protocol version "
55 + std::to_string(version);
56}
57
Steven Morelanddea3cf92019-07-16 18:06:55 -070058void Stability::markCompilationUnit(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000059 auto stability = Category::currentFromLevel(getLocalLevel());
Steven Morelande35fef32021-03-23 01:38:24 +000060 status_t result = setRepr(binder, stability.repr(), REPR_LOG);
Steven Morelanddea3cf92019-07-16 18:06:55 -070061 LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
62}
63
64void Stability::markVintf(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000065 auto stability = Category::currentFromLevel(Level::VINTF);
Steven Morelande35fef32021-03-23 01:38:24 +000066 status_t result = setRepr(binder, stability.repr(), REPR_LOG);
Steven Morelanddea3cf92019-07-16 18:06:55 -070067 LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
68}
69
Steven Moreland64ae9172019-08-02 20:45:15 -070070void Stability::debugLogStability(const std::string& tag, const sp<IBinder>& binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000071 auto stability = getCategory(binder.get());
72 ALOGE("%s: stability is %s", tag.c_str(), stability.debugString().c_str());
Steven Moreland64ae9172019-08-02 20:45:15 -070073}
74
Steven Morelandc709dd82019-08-05 20:30:14 -070075void Stability::markVndk(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000076 auto stability = Category::currentFromLevel(Level::VENDOR);
Steven Morelande35fef32021-03-23 01:38:24 +000077 status_t result = setRepr(binder, stability.repr(), REPR_LOG);
Steven Morelandc709dd82019-08-05 20:30:14 -070078 LOG_ALWAYS_FATAL_IF(result != OK, "Should only mark known object.");
79}
80
Steven Moreland86a17f82019-09-10 10:18:00 -070081bool Stability::requiresVintfDeclaration(const sp<IBinder>& binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000082 return check(getCategory(binder.get()), Level::VINTF);
Steven Moreland86a17f82019-09-10 10:18:00 -070083}
84
Steven Moreland2a9f32f2019-07-31 17:51:25 -070085void Stability::tryMarkCompilationUnit(IBinder* binder) {
Steven Moreland89ddfc52020-11-13 02:39:26 +000086 auto stability = Category::currentFromLevel(getLocalLevel());
Steven Morelande35fef32021-03-23 01:38:24 +000087 (void) setRepr(binder, stability.repr(), REPR_NONE);
Steven Moreland2f2c4e02020-07-28 18:11:21 +000088}
89
Steven Moreland89ddfc52020-11-13 02:39:26 +000090Stability::Level Stability::getLocalLevel() {
Steven Morelandb6c7e222021-02-18 19:20:14 +000091#ifdef __ANDROID_APEX__
92#error APEX can't use libbinder (must use libbinder_ndk)
93#endif
94
Steven Moreland2f2c4e02020-07-28 18:11:21 +000095#ifdef __ANDROID_VNDK__
Steven Morelandb6c7e222021-02-18 19:20:14 +000096 return Level::VENDOR;
Steven Moreland2f2c4e02020-07-28 18:11:21 +000097#else
98 // TODO(b/139325195): split up stability levels for system/APEX.
99 return Level::SYSTEM;
100#endif
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700101}
102
Steven Morelande35fef32021-03-23 01:38:24 +0000103status_t Stability::setRepr(IBinder* binder, int32_t representation, uint32_t flags) {
104 bool log = flags & REPR_LOG;
105 bool allowDowngrade = flags & REPR_ALLOW_DOWNGRADE;
106
Steven Moreland89ddfc52020-11-13 02:39:26 +0000107 auto current = getCategory(binder);
108 auto setting = Category::fromRepr(representation);
109
110 // If we have ahold of a binder with a newer declared version, then it
111 // should support older versions, and we will simply write our parcels with
112 // the current wire parcel format.
113 if (setting.version < kBinderWireFormatOldest) {
114 // always log, because this shouldn't happen
115 ALOGE("Cannot accept binder with older binder wire protocol version "
116 "%u. Versions less than %u are unsupported.", setting.version,
117 kBinderWireFormatOldest);
118 return BAD_TYPE;
119 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700120
121 // null binder is always written w/ 'UNDECLARED' stability
122 if (binder == nullptr) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000123 if (setting.level == UNDECLARED) {
Steven Morelanddea3cf92019-07-16 18:06:55 -0700124 return OK;
125 } else {
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700126 if (log) {
127 ALOGE("Null binder written with stability %s.",
Steven Moreland89ddfc52020-11-13 02:39:26 +0000128 levelString(setting.level).c_str());
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700129 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700130 return BAD_TYPE;
131 }
132 }
133
Steven Moreland89ddfc52020-11-13 02:39:26 +0000134 if (!isDeclaredLevel(setting.level)) {
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700135 if (log) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000136 ALOGE("Can only set known stability, not %u.", setting.level);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700137 }
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700138 return BAD_TYPE;
Steven Morelanddea3cf92019-07-16 18:06:55 -0700139 }
140
Steven Morelande35fef32021-03-23 01:38:24 +0000141 if (current == setting) return OK;
142
143 bool hasAlreadyBeenSet = current.repr() != 0;
144 bool isAllowedDowngrade = allowDowngrade && check(current, setting.level);
145 if (hasAlreadyBeenSet && !isAllowedDowngrade) {
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700146 if (log) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000147 ALOGE("Interface being set with %s but it is already marked as %s",
148 setting.debugString().c_str(),
149 current.debugString().c_str());
Steven Moreland2a9f32f2019-07-31 17:51:25 -0700150 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700151 return BAD_TYPE;
152 }
153
Steven Morelande35fef32021-03-23 01:38:24 +0000154 if (isAllowedDowngrade) {
155 ALOGI("Interface set with %s downgraded to %s stability",
156 current.debugString().c_str(),
157 setting.debugString().c_str());
158 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700159
Steven Morelanda7fb0182020-02-26 16:02:08 -0800160 BBinder* local = binder->localBinder();
161 if (local != nullptr) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000162 local->mStability = setting.repr();
Steven Morelanda7fb0182020-02-26 16:02:08 -0800163 } else {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000164 binder->remoteBinder()->mStability = setting.repr();
Steven Morelanda7fb0182020-02-26 16:02:08 -0800165 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700166
167 return OK;
168}
169
Steven Moreland89ddfc52020-11-13 02:39:26 +0000170Stability::Category Stability::getCategory(IBinder* binder) {
171 if (binder == nullptr) {
172 return Category::currentFromLevel(Level::UNDECLARED);
173 }
Steven Morelanddea3cf92019-07-16 18:06:55 -0700174
Steven Morelanda7fb0182020-02-26 16:02:08 -0800175 BBinder* local = binder->localBinder();
176 if (local != nullptr) {
Steven Moreland89ddfc52020-11-13 02:39:26 +0000177 return Category::fromRepr(local->mStability);
Steven Morelanda7fb0182020-02-26 16:02:08 -0800178 }
179
Steven Moreland89ddfc52020-11-13 02:39:26 +0000180 return Category::fromRepr(binder->remoteBinder()->mStability);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700181}
182
Steven Moreland89ddfc52020-11-13 02:39:26 +0000183bool Stability::check(Category provided, Level required) {
184 bool stable = (provided.level & required) == required;
Steven Morelanddea3cf92019-07-16 18:06:55 -0700185
Steven Moreland89ddfc52020-11-13 02:39:26 +0000186 if (provided.level != UNDECLARED && !isDeclaredLevel(provided.level)) {
187 ALOGE("Unknown stability when checking interface stability %d.",
188 provided.level);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700189
190 stable = false;
191 }
192
Steven Morelanddea3cf92019-07-16 18:06:55 -0700193 return stable;
194}
195
Steven Moreland89ddfc52020-11-13 02:39:26 +0000196bool Stability::isDeclaredLevel(Level stability) {
Steven Morelanddea3cf92019-07-16 18:06:55 -0700197 return stability == VENDOR || stability == SYSTEM || stability == VINTF;
198}
199
Steven Moreland89ddfc52020-11-13 02:39:26 +0000200std::string Stability::levelString(Level level) {
201 switch (level) {
Steven Morelanddea3cf92019-07-16 18:06:55 -0700202 case Level::UNDECLARED: return "undeclared stability";
203 case Level::VENDOR: return "vendor stability";
204 case Level::SYSTEM: return "system stability";
205 case Level::VINTF: return "vintf stability";
206 }
Steven Moreland89ddfc52020-11-13 02:39:26 +0000207 return "unknown stability " + std::to_string(level);
Steven Morelanddea3cf92019-07-16 18:06:55 -0700208}
209
210} // namespace internal
Steven Moreland86a17f82019-09-10 10:18:00 -0700211} // namespace stability