blob: 07809e21f479246f6e14440dcec28f4f357772cf [file] [log] [blame]
Steven Moreland80e1e6d2019-06-21 12:35:59 -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 */
16
17#include "ServiceManager.h"
18
19#include <android-base/logging.h>
Jon Spivack0d844302019-07-22 18:40:34 -070020#include <android-base/properties.h>
Jon Spivack9f503a42019-10-22 16:49:19 -070021#include <binder/BpBinder.h>
22#include <binder/IPCThreadState.h>
23#include <binder/ProcessState.h>
Steven Moreland86a17f82019-09-10 10:18:00 -070024#include <binder/Stability.h>
Steven Moreland80e1e6d2019-06-21 12:35:59 -070025#include <cutils/android_filesystem_config.h>
26#include <cutils/multiuser.h>
Jon Spivack0d844302019-07-22 18:40:34 -070027#include <thread>
Steven Moreland80e1e6d2019-06-21 12:35:59 -070028
Steven Moreland86a17f82019-09-10 10:18:00 -070029#ifndef VENDORSERVICEMANAGER
30#include <vintf/VintfObject.h>
Yifan Hong0a9b56e2021-11-30 16:45:40 -080031#ifdef __ANDROID_RECOVERY__
32#include <vintf/VintfObjectRecovery.h>
33#endif // __ANDROID_RECOVERY__
Steven Moreland86a17f82019-09-10 10:18:00 -070034#include <vintf/constants.h>
35#endif // !VENDORSERVICEMANAGER
36
Steven Moreland80e1e6d2019-06-21 12:35:59 -070037using ::android::binder::Status;
Steven Moreland86a17f82019-09-10 10:18:00 -070038using ::android::internal::Stability;
Steven Moreland80e1e6d2019-06-21 12:35:59 -070039
40namespace android {
41
Steven Morelandb9e1cbe2023-02-01 22:44:45 +000042bool is_multiuser_uid_isolated(uid_t uid) {
43 uid_t appid = multiuser_get_app_id(uid);
44 return appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
45}
46
Steven Moreland86a17f82019-09-10 10:18:00 -070047#ifndef VENDORSERVICEMANAGER
Yifan Hong0a9b56e2021-11-30 16:45:40 -080048
Steven Moreland2e293aa2020-09-23 00:25:16 +000049struct ManifestWithDescription {
50 std::shared_ptr<const vintf::HalManifest> manifest;
51 const char* description;
52};
Yifan Hong0a9b56e2021-11-30 16:45:40 -080053static std::vector<ManifestWithDescription> GetManifestsWithDescription() {
54#ifdef __ANDROID_RECOVERY__
55 auto vintfObject = vintf::VintfObjectRecovery::GetInstance();
56 if (vintfObject == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000057 ALOGE("NULL VintfObjectRecovery!");
Yifan Hong0a9b56e2021-11-30 16:45:40 -080058 return {};
59 }
60 return {ManifestWithDescription{vintfObject->getRecoveryHalManifest(), "recovery"}};
61#else
62 auto vintfObject = vintf::VintfObject::GetInstance();
63 if (vintfObject == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000064 ALOGE("NULL VintfObject!");
Yifan Hong0a9b56e2021-11-30 16:45:40 -080065 return {};
66 }
67 return {ManifestWithDescription{vintfObject->getDeviceHalManifest(), "device"},
68 ManifestWithDescription{vintfObject->getFrameworkHalManifest(), "framework"}};
69#endif
70}
71
Steven Moreland2e293aa2020-09-23 00:25:16 +000072// func true -> stop search and forEachManifest will return true
73static bool forEachManifest(const std::function<bool(const ManifestWithDescription&)>& func) {
Yifan Hong0a9b56e2021-11-30 16:45:40 -080074 for (const ManifestWithDescription& mwd : GetManifestsWithDescription()) {
Steven Moreland2e293aa2020-09-23 00:25:16 +000075 if (mwd.manifest == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000076 ALOGE("NULL VINTF MANIFEST!: %s", mwd.description);
77 // note, we explicitly do not retry here, so that we can detect VINTF
78 // or other bugs (b/151696835)
79 continue;
Steven Moreland2e293aa2020-09-23 00:25:16 +000080 }
81 if (func(mwd)) return true;
82 }
83 return false;
84}
85
Steven Morelandedd4e072021-04-21 00:27:29 +000086struct AidlName {
87 std::string package;
88 std::string iface;
89 std::string instance;
Steven Moreland86a17f82019-09-10 10:18:00 -070090
Steven Morelandedd4e072021-04-21 00:27:29 +000091 static bool fill(const std::string& name, AidlName* aname) {
92 size_t firstSlash = name.find('/');
93 size_t lastDot = name.rfind('.', firstSlash);
94 if (firstSlash == std::string::npos || lastDot == std::string::npos) {
Pawan Wagh37526162022-09-29 21:55:26 +000095 ALOGE("VINTF HALs require names in the format type/instance (e.g. "
96 "some.package.foo.IFoo/default) but got: %s",
97 name.c_str());
Steven Morelandedd4e072021-04-21 00:27:29 +000098 return false;
99 }
100 aname->package = name.substr(0, lastDot);
101 aname->iface = name.substr(lastDot + 1, firstSlash - lastDot - 1);
102 aname->instance = name.substr(firstSlash + 1);
103 return true;
104 }
105};
106
107static bool isVintfDeclared(const std::string& name) {
108 AidlName aname;
109 if (!AidlName::fill(name, &aname)) return false;
110
111 bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
112 if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000113 ALOGI("Found %s in %s VINTF manifest.", name.c_str(), mwd.description);
Steven Morelandedd4e072021-04-21 00:27:29 +0000114 return true; // break
Steven Moreland86a17f82019-09-10 10:18:00 -0700115 }
Steven Moreland2e293aa2020-09-23 00:25:16 +0000116 return false; // continue
117 });
118
119 if (!found) {
120 // Although it is tested, explicitly rebuilding qualified name, in case it
121 // becomes something unexpected.
Pawan Wagh37526162022-09-29 21:55:26 +0000122 ALOGI("Could not find %s.%s/%s in the VINTF manifest.", aname.package.c_str(),
123 aname.iface.c_str(), aname.instance.c_str());
Steven Moreland86a17f82019-09-10 10:18:00 -0700124 }
Steven Moreland2edde8e2020-04-30 17:04:54 -0700125
Steven Moreland2e293aa2020-09-23 00:25:16 +0000126 return found;
127}
128
Steven Morelandedd4e072021-04-21 00:27:29 +0000129static std::optional<std::string> getVintfUpdatableApex(const std::string& name) {
130 AidlName aname;
131 if (!AidlName::fill(name, &aname)) return std::nullopt;
132
133 std::optional<std::string> updatableViaApex;
134
135 forEachManifest([&](const ManifestWithDescription& mwd) {
136 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
137 if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
138 if (manifestInstance.package() != aname.package) return true;
139 if (manifestInstance.interface() != aname.iface) return true;
140 if (manifestInstance.instance() != aname.instance) return true;
141 updatableViaApex = manifestInstance.updatableViaApex();
142 return false; // break (libvintf uses opposite convention)
143 });
Jooyung Hance94b752022-11-14 18:55:06 +0900144 if (updatableViaApex.has_value()) return true; // break (found match)
Steven Morelandedd4e072021-04-21 00:27:29 +0000145 return false; // continue
146 });
147
148 return updatableViaApex;
149}
150
Jooyung Han76944fe2022-10-25 17:02:45 +0900151static std::vector<std::string> getVintfUpdatableInstances(const std::string& apexName) {
152 std::vector<std::string> instances;
153
154 forEachManifest([&](const ManifestWithDescription& mwd) {
155 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
156 if (manifestInstance.format() == vintf::HalFormat::AIDL &&
157 manifestInstance.updatableViaApex().has_value() &&
158 manifestInstance.updatableViaApex().value() == apexName) {
159 std::string aname = manifestInstance.package() + "." +
160 manifestInstance.interface() + "/" + manifestInstance.instance();
161 instances.push_back(aname);
162 }
Jooyung Hance94b752022-11-14 18:55:06 +0900163 return true; // continue (libvintf uses opposite convention)
Jooyung Han76944fe2022-10-25 17:02:45 +0900164 });
165 return false; // continue
166 });
167
168 return instances;
169}
170
Devin Moore5e4c2f12021-09-09 22:36:33 +0000171static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
172 AidlName aname;
173 if (!AidlName::fill(name, &aname)) return std::nullopt;
174
175 std::optional<std::string> ip;
176 std::optional<uint64_t> port;
177 forEachManifest([&](const ManifestWithDescription& mwd) {
178 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
179 if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
180 if (manifestInstance.package() != aname.package) return true;
181 if (manifestInstance.interface() != aname.iface) return true;
182 if (manifestInstance.instance() != aname.instance) return true;
183 ip = manifestInstance.ip();
184 port = manifestInstance.port();
185 return false; // break (libvintf uses opposite convention)
186 });
187 return false; // continue
188 });
189
190 if (ip.has_value() && port.has_value()) {
191 ConnectionInfo info;
192 info.ipAddress = *ip;
193 info.port = *port;
194 return std::make_optional<ConnectionInfo>(info);
195 } else {
196 return std::nullopt;
197 }
198}
199
Steven Moreland2e293aa2020-09-23 00:25:16 +0000200static std::vector<std::string> getVintfInstances(const std::string& interface) {
201 size_t lastDot = interface.rfind('.');
202 if (lastDot == std::string::npos) {
Pawan Wagh37526162022-09-29 21:55:26 +0000203 ALOGE("VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) "
204 "but got: %s",
205 interface.c_str());
Steven Moreland2e293aa2020-09-23 00:25:16 +0000206 return {};
207 }
208 const std::string package = interface.substr(0, lastDot);
209 const std::string iface = interface.substr(lastDot+1);
210
211 std::vector<std::string> ret;
212 (void)forEachManifest([&](const ManifestWithDescription& mwd) {
213 auto instances = mwd.manifest->getAidlInstances(package, iface);
214 ret.insert(ret.end(), instances.begin(), instances.end());
215 return false; // continue
216 });
217
218 return ret;
Steven Moreland86a17f82019-09-10 10:18:00 -0700219}
Steven Morelandb82b8f82019-10-28 10:52:34 -0700220
221static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
222 if (!Stability::requiresVintfDeclaration(binder)) {
223 return true;
224 }
225
226 return isVintfDeclared(name);
227}
Steven Moreland86a17f82019-09-10 10:18:00 -0700228#endif // !VENDORSERVICEMANAGER
229
Steven Morelandb8361902023-02-01 23:18:04 +0000230ServiceManager::Service::~Service() {
231 if (!hasClients) {
232 // only expected to happen on process death
233 LOG(WARNING) << "a service was removed when there are clients";
234 }
235}
236
Steven Morelandd13f08b2019-11-18 14:23:09 -0800237ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700238// TODO(b/151696835): reenable performance hack when we solve bug, since with
239// this hack and other fixes, it is unlikely we will see even an ephemeral
240// failure when the manifest parse fails. The goal is that the manifest will
241// be read incorrectly and cause the process trying to register a HAL to
242// fail. If this is in fact an early boot kernel contention issue, then we
243// will get no failure, and by its absence, be signalled to invest more
244// effort in re-adding this performance hack.
245// #ifndef VENDORSERVICEMANAGER
246// // can process these at any times, don't want to delay first VINTF client
247// std::thread([] {
248// vintf::VintfObject::GetDeviceHalManifest();
249// vintf::VintfObject::GetFrameworkHalManifest();
250// }).detach();
251// #endif // !VENDORSERVICEMANAGER
Steven Morelandd13f08b2019-11-18 14:23:09 -0800252}
Steven Moreland130242d2019-08-26 17:41:32 -0700253ServiceManager::~ServiceManager() {
254 // this should only happen in tests
255
Jon Spivackf288b1d2019-12-19 17:15:51 -0800256 for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700257 CHECK(!callbacks.empty()) << name;
258 for (const auto& callback : callbacks) {
259 CHECK(callback != nullptr) << name;
260 }
261 }
262
Steven Moreland130242d2019-08-26 17:41:32 -0700263 for (const auto& [name, service] : mNameToService) {
264 CHECK(service.binder != nullptr) << name;
265 }
266}
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700267
268Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700269 *outBinder = tryGetService(name, true);
270 // returns ok regardless of result for legacy reasons
271 return Status::ok();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700272}
273
274Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700275 *outBinder = tryGetService(name, false);
276 // returns ok regardless of result for legacy reasons
277 return Status::ok();
278}
279
280sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700281 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700282
Jon Spivack0d844302019-07-22 18:40:34 -0700283 sp<IBinder> out;
Jon Spivack9f503a42019-10-22 16:49:19 -0700284 Service* service = nullptr;
Jon Spivack0d844302019-07-22 18:40:34 -0700285 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700286 service = &(it->second);
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700287
Steven Morelandb9e1cbe2023-02-01 22:44:45 +0000288 if (!service->allowIsolated && is_multiuser_uid_isolated(ctx.uid)) {
289 return nullptr;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700290 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700291 out = service->binder;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700292 }
293
Steven Morelanda9fe4742019-07-18 14:45:20 -0700294 if (!mAccess->canFind(ctx, name)) {
Jon Spivack0d844302019-07-22 18:40:34 -0700295 return nullptr;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700296 }
297
Jon Spivack0d844302019-07-22 18:40:34 -0700298 if (!out && startIfNotFound) {
299 tryStartService(name);
300 }
301
Jon Spivack9f503a42019-10-22 16:49:19 -0700302 if (out) {
Steven Morelandb8361902023-02-01 23:18:04 +0000303 // Force onClients to get sent, and then make sure the timerfd won't clear it
304 // by setting guaranteeClient again. This logic could be simplified by using
305 // a time-based guarantee. However, forcing onClients(true) to get sent
306 // right here is always going to be important for processes serving multiple
307 // lazy interfaces.
308 service->guaranteeClient = true;
309 CHECK(handleServiceClientCallback(2 /* sm + transaction */, name, false));
Jon Spivack9f503a42019-10-22 16:49:19 -0700310 service->guaranteeClient = true;
311 }
312
Jon Spivack0d844302019-07-22 18:40:34 -0700313 return out;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700314}
315
Steven Moreland905e2e82019-07-17 11:05:45 -0700316bool isValidServiceName(const std::string& name) {
317 if (name.size() == 0) return false;
318 if (name.size() > 127) return false;
319
320 for (char c : name) {
Steven Morelandbb7951d2019-08-20 16:58:25 -0700321 if (c == '_' || c == '-' || c == '.' || c == '/') continue;
Steven Moreland905e2e82019-07-17 11:05:45 -0700322 if (c >= 'a' && c <= 'z') continue;
323 if (c >= 'A' && c <= 'Z') continue;
324 if (c >= '0' && c <= '9') continue;
325 return false;
326 }
327
328 return true;
329}
330
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700331Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700332 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700333
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700334 if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000335 return Status::fromExceptionCode(Status::EX_SECURITY, "App UIDs cannot add services");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700336 }
337
Steven Morelanda9fe4742019-07-18 14:45:20 -0700338 if (!mAccess->canAdd(ctx, name)) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000339 return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700340 }
341
342 if (binder == nullptr) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000343 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Null binder");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700344 }
345
Steven Moreland905e2e82019-07-17 11:05:45 -0700346 if (!isValidServiceName(name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000347 ALOGE("Invalid service name: %s", name.c_str());
Steven Morelandac2d2852022-03-18 18:15:20 +0000348 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700349 }
350
Steven Moreland86a17f82019-09-10 10:18:00 -0700351#ifndef VENDORSERVICEMANAGER
352 if (!meetsDeclarationRequirements(binder, name)) {
353 // already logged
Steven Morelandac2d2852022-03-18 18:15:20 +0000354 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "VINTF declaration error");
Steven Moreland86a17f82019-09-10 10:18:00 -0700355 }
356#endif // !VENDORSERVICEMANAGER
357
Steven Moreland88860b02019-08-12 14:24:14 -0700358 // implicitly unlinked when the binder is removed
Steven Morelandb0983182021-04-02 03:14:04 +0000359 if (binder->remoteBinder() != nullptr &&
360 binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
Pawan Wagh37526162022-09-29 21:55:26 +0000361 ALOGE("Could not linkToDeath when adding %s", name.c_str());
Steven Morelandac2d2852022-03-18 18:15:20 +0000362 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "linkToDeath failure");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700363 }
364
Steven Moreland7ee423b2022-09-24 03:52:08 +0000365 auto it = mNameToService.find(name);
366 if (it != mNameToService.end()) {
367 const Service& existing = it->second;
368
369 // We could do better than this because if the other service dies, it
370 // may not have an entry here. However, this case is unlikely. We are
371 // only trying to detect when two different services are accidentally installed.
372
373 if (existing.ctx.uid != ctx.uid) {
Pawan Wagh37526162022-09-29 21:55:26 +0000374 ALOGW("Service '%s' originally registered from UID %u but it is now being registered "
375 "from UID %u. Multiple instances installed?",
376 name.c_str(), existing.ctx.uid, ctx.uid);
Steven Moreland7ee423b2022-09-24 03:52:08 +0000377 }
378
379 if (existing.ctx.sid != ctx.sid) {
Pawan Wagh37526162022-09-29 21:55:26 +0000380 ALOGW("Service '%s' originally registered from SID %s but it is now being registered "
381 "from SID %s. Multiple instances installed?",
382 name.c_str(), existing.ctx.sid.c_str(), ctx.sid.c_str());
Steven Moreland7ee423b2022-09-24 03:52:08 +0000383 }
384
Pawan Wagh37526162022-09-29 21:55:26 +0000385 ALOGI("Service '%s' originally registered from PID %d but it is being registered again "
386 "from PID %d. Bad state? Late death notification? Multiple instances installed?",
387 name.c_str(), existing.ctx.debugPid, ctx.debugPid);
Steven Moreland7ee423b2022-09-24 03:52:08 +0000388 }
389
Devin Moore05ffe522020-08-06 13:58:29 -0700390 // Overwrite the old service if it exists
Steven Moreland7ee423b2022-09-24 03:52:08 +0000391 mNameToService[name] = Service{
392 .binder = binder,
393 .allowIsolated = allowIsolated,
394 .dumpPriority = dumpPriority,
395 .ctx = ctx,
Devin Moore05ffe522020-08-06 13:58:29 -0700396 };
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700397
Steven Moreland7ee423b2022-09-24 03:52:08 +0000398 if (auto it = mNameToRegistrationCallback.find(name); it != mNameToRegistrationCallback.end()) {
Steven Morelandb8361902023-02-01 23:18:04 +0000399 // See also getService - handles case where client never gets the service,
400 // we want the service to quit.
401 mNameToService[name].guaranteeClient = true;
402 CHECK(handleServiceClientCallback(2 /* sm + transaction */, name, false));
403 mNameToService[name].guaranteeClient = true;
404
Steven Moreland27cfab02019-08-12 14:34:16 -0700405 for (const sp<IServiceCallback>& cb : it->second) {
406 // permission checked in registerForNotifications
407 cb->onRegistration(name, binder);
408 }
409 }
410
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700411 return Status::ok();
412}
413
414Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700415 if (!mAccess->canList(mAccess->getCallingContext())) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700416 return Status::fromExceptionCode(Status::EX_SECURITY);
417 }
418
419 size_t toReserve = 0;
420 for (auto const& [name, service] : mNameToService) {
421 (void) name;
422
423 if (service.dumpPriority & dumpPriority) ++toReserve;
424 }
425
426 CHECK(outList->empty());
427
428 outList->reserve(toReserve);
429 for (auto const& [name, service] : mNameToService) {
430 (void) service;
431
432 if (service.dumpPriority & dumpPriority) {
433 outList->push_back(name);
434 }
435 }
436
437 return Status::ok();
438}
439
Steven Moreland27cfab02019-08-12 14:34:16 -0700440Status ServiceManager::registerForNotifications(
441 const std::string& name, const sp<IServiceCallback>& callback) {
442 auto ctx = mAccess->getCallingContext();
443
444 if (!mAccess->canFind(ctx, name)) {
Steven Morelandb9e1cbe2023-02-01 22:44:45 +0000445 return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux");
446 }
447
448 // note - we could allow isolated apps to get notifications if we
449 // keep track of isolated callbacks and non-isolated callbacks, but
450 // this is done since isolated apps shouldn't access lazy services
451 // so we should be able to use different APIs to keep things simple.
452 // Here, we disallow everything, because the service might not be
453 // registered yet.
454 if (is_multiuser_uid_isolated(ctx.uid)) {
455 return Status::fromExceptionCode(Status::EX_SECURITY, "isolated app");
Steven Moreland27cfab02019-08-12 14:34:16 -0700456 }
457
458 if (!isValidServiceName(name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000459 ALOGE("Invalid service name: %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700460 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
461 }
462
463 if (callback == nullptr) {
464 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
465 }
466
Steven Morelandb0983182021-04-02 03:14:04 +0000467 if (OK !=
468 IInterface::asBinder(callback)->linkToDeath(
469 sp<ServiceManager>::fromExisting(this))) {
Pawan Wagh37526162022-09-29 21:55:26 +0000470 ALOGE("Could not linkToDeath when adding %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700471 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
472 }
473
Jon Spivackf288b1d2019-12-19 17:15:51 -0800474 mNameToRegistrationCallback[name].push_back(callback);
Steven Moreland27cfab02019-08-12 14:34:16 -0700475
476 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
477 const sp<IBinder>& binder = it->second.binder;
478
479 // never null if an entry exists
480 CHECK(binder != nullptr) << name;
481 callback->onRegistration(name, binder);
482 }
483
484 return Status::ok();
485}
486Status ServiceManager::unregisterForNotifications(
487 const std::string& name, const sp<IServiceCallback>& callback) {
488 auto ctx = mAccess->getCallingContext();
489
490 if (!mAccess->canFind(ctx, name)) {
491 return Status::fromExceptionCode(Status::EX_SECURITY);
492 }
493
494 bool found = false;
495
Jon Spivackf288b1d2019-12-19 17:15:51 -0800496 auto it = mNameToRegistrationCallback.find(name);
497 if (it != mNameToRegistrationCallback.end()) {
498 removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
Steven Moreland27cfab02019-08-12 14:34:16 -0700499 }
500
501 if (!found) {
Pawan Wagh37526162022-09-29 21:55:26 +0000502 ALOGE("Trying to unregister callback, but none exists %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700503 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
504 }
505
506 return Status::ok();
507}
508
Steven Morelandb82b8f82019-10-28 10:52:34 -0700509Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
510 auto ctx = mAccess->getCallingContext();
511
512 if (!mAccess->canFind(ctx, name)) {
513 return Status::fromExceptionCode(Status::EX_SECURITY);
514 }
515
516 *outReturn = false;
517
518#ifndef VENDORSERVICEMANAGER
519 *outReturn = isVintfDeclared(name);
520#endif
521 return Status::ok();
522}
523
Steven Moreland2e293aa2020-09-23 00:25:16 +0000524binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
525 auto ctx = mAccess->getCallingContext();
526
527 std::vector<std::string> allInstances;
528#ifndef VENDORSERVICEMANAGER
529 allInstances = getVintfInstances(interface);
530#endif
531
532 outReturn->clear();
533
534 for (const std::string& instance : allInstances) {
Steven Moreland2e293aa2020-09-23 00:25:16 +0000535 if (mAccess->canFind(ctx, interface + "/" + instance)) {
536 outReturn->push_back(instance);
537 }
538 }
539
540 if (outReturn->size() == 0 && allInstances.size() != 0) {
541 return Status::fromExceptionCode(Status::EX_SECURITY);
542 }
543
544 return Status::ok();
545}
546
Steven Morelandedd4e072021-04-21 00:27:29 +0000547Status ServiceManager::updatableViaApex(const std::string& name,
548 std::optional<std::string>* outReturn) {
549 auto ctx = mAccess->getCallingContext();
550
551 if (!mAccess->canFind(ctx, name)) {
552 return Status::fromExceptionCode(Status::EX_SECURITY);
553 }
554
555 *outReturn = std::nullopt;
556
557#ifndef VENDORSERVICEMANAGER
558 *outReturn = getVintfUpdatableApex(name);
559#endif
560 return Status::ok();
561}
562
Jooyung Han76944fe2022-10-25 17:02:45 +0900563Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName,
564 std::vector<std::string>* outReturn) {
565 auto ctx = mAccess->getCallingContext();
566
567 std::vector<std::string> apexUpdatableInstances;
568#ifndef VENDORSERVICEMANAGER
569 apexUpdatableInstances = getVintfUpdatableInstances(apexName);
570#endif
571
572 outReturn->clear();
573
574 for (const std::string& instance : apexUpdatableInstances) {
575 if (mAccess->canFind(ctx, instance)) {
576 outReturn->push_back(instance);
577 }
578 }
579
580 if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) {
581 return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
582 }
583
584 return Status::ok();
585}
586
Devin Moore5e4c2f12021-09-09 22:36:33 +0000587Status ServiceManager::getConnectionInfo(const std::string& name,
588 std::optional<ConnectionInfo>* outReturn) {
589 auto ctx = mAccess->getCallingContext();
590
591 if (!mAccess->canFind(ctx, name)) {
592 return Status::fromExceptionCode(Status::EX_SECURITY);
593 }
594
595 *outReturn = std::nullopt;
596
597#ifndef VENDORSERVICEMANAGER
598 *outReturn = getVintfConnectionInfo(name);
599#endif
600 return Status::ok();
601}
602
Jon Spivackf288b1d2019-12-19 17:15:51 -0800603void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
604 ServiceCallbackMap::iterator* it,
Steven Moreland27cfab02019-08-12 14:34:16 -0700605 bool* found) {
606 std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
607
608 for (auto lit = listeners.begin(); lit != listeners.end();) {
609 if (IInterface::asBinder(*lit) == who) {
610 if(found) *found = true;
611 lit = listeners.erase(lit);
612 } else {
613 ++lit;
614 }
615 }
616
617 if (listeners.empty()) {
Jon Spivackf288b1d2019-12-19 17:15:51 -0800618 *it = mNameToRegistrationCallback.erase(*it);
Steven Moreland27cfab02019-08-12 14:34:16 -0700619 } else {
Jon Spivacke223f082019-11-19 16:21:20 -0800620 (*it)++;
Steven Moreland27cfab02019-08-12 14:34:16 -0700621 }
622}
623
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700624void ServiceManager::binderDied(const wp<IBinder>& who) {
625 for (auto it = mNameToService.begin(); it != mNameToService.end();) {
626 if (who == it->second.binder) {
627 it = mNameToService.erase(it);
628 } else {
629 ++it;
630 }
631 }
Steven Moreland27cfab02019-08-12 14:34:16 -0700632
Jon Spivackf288b1d2019-12-19 17:15:51 -0800633 for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
634 removeRegistrationCallback(who, &it, nullptr /*found*/);
Steven Moreland27cfab02019-08-12 14:34:16 -0700635 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700636
637 for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
638 removeClientCallback(who, &it);
639 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700640}
641
Jon Spivack0d844302019-07-22 18:40:34 -0700642void ServiceManager::tryStartService(const std::string& name) {
Steven Morelandba0f33c2022-11-04 22:24:31 +0000643 ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service. (if it's not "
644 "configured to be a lazy service, it may be stuck starting or still starting).",
Jon Spivack0d844302019-07-22 18:40:34 -0700645 name.c_str());
646
647 std::thread([=] {
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000648 if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000649 ALOGI("Tried to start aidl service %s as a lazy service, but was unable to. Usually "
650 "this happens when a "
651 "service is not installed, but if the service is intended to be used as a "
652 "lazy service, then it may be configured incorrectly.",
653 name.c_str());
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000654 }
Jon Spivack0d844302019-07-22 18:40:34 -0700655 }).detach();
656}
657
Jon Spivack9f503a42019-10-22 16:49:19 -0700658Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
659 const sp<IClientCallback>& cb) {
660 if (cb == nullptr) {
661 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
662 }
663
664 auto ctx = mAccess->getCallingContext();
665 if (!mAccess->canAdd(ctx, name)) {
666 return Status::fromExceptionCode(Status::EX_SECURITY);
667 }
668
669 auto serviceIt = mNameToService.find(name);
670 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000671 ALOGE("Could not add callback for nonexistent service: %s", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700672 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
673 }
674
Steven Moreland7ee423b2022-09-24 03:52:08 +0000675 if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000676 ALOGW("Only a server can register for client callbacks (for %s)", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700677 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
678 }
679
680 if (serviceIt->second.binder != service) {
Pawan Wagh37526162022-09-29 21:55:26 +0000681 ALOGW("Tried to register client callback for %s but a different service is registered "
682 "under this name.",
683 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700684 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
685 }
686
Steven Morelandb0983182021-04-02 03:14:04 +0000687 if (OK !=
688 IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
Pawan Wagh37526162022-09-29 21:55:26 +0000689 ALOGE("Could not linkToDeath when adding client callback for %s", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700690 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
691 }
692
693 mNameToClientCallback[name].push_back(cb);
694
695 return Status::ok();
696}
697
698void ServiceManager::removeClientCallback(const wp<IBinder>& who,
699 ClientCallbackMap::iterator* it) {
700 std::vector<sp<IClientCallback>>& listeners = (*it)->second;
701
702 for (auto lit = listeners.begin(); lit != listeners.end();) {
703 if (IInterface::asBinder(*lit) == who) {
704 lit = listeners.erase(lit);
705 } else {
706 ++lit;
707 }
708 }
709
710 if (listeners.empty()) {
711 *it = mNameToClientCallback.erase(*it);
712 } else {
713 (*it)++;
714 }
715}
716
717ssize_t ServiceManager::Service::getNodeStrongRefCount() {
Steven Morelandb0983182021-04-02 03:14:04 +0000718 sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
Jon Spivack9f503a42019-10-22 16:49:19 -0700719 if (bpBinder == nullptr) return -1;
720
Steven Morelande8393882020-12-18 02:27:20 +0000721 return ProcessState::self()->getStrongRefCountForNode(bpBinder);
Jon Spivack9f503a42019-10-22 16:49:19 -0700722}
723
724void ServiceManager::handleClientCallbacks() {
725 for (const auto& [name, service] : mNameToService) {
Steven Morelandb8361902023-02-01 23:18:04 +0000726 handleServiceClientCallback(1 /* sm has one refcount */, name, true);
Jon Spivack9f503a42019-10-22 16:49:19 -0700727 }
728}
729
Steven Morelandb8361902023-02-01 23:18:04 +0000730bool ServiceManager::handleServiceClientCallback(size_t knownClients,
731 const std::string& serviceName,
732 bool isCalledOnInterval) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700733 auto serviceIt = mNameToService.find(serviceName);
734 if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
Steven Morelandb8361902023-02-01 23:18:04 +0000735 return true; // return we do have clients a.k.a. DON'T DO ANYTHING
Jon Spivack9f503a42019-10-22 16:49:19 -0700736 }
737
738 Service& service = serviceIt->second;
739 ssize_t count = service.getNodeStrongRefCount();
740
Steven Morelandb8361902023-02-01 23:18:04 +0000741 // binder driver doesn't support this feature, consider we have clients
742 if (count == -1) return true;
Jon Spivack9f503a42019-10-22 16:49:19 -0700743
Steven Morelandb8361902023-02-01 23:18:04 +0000744 bool hasKernelReportedClients = static_cast<size_t>(count) > knownClients;
Jon Spivack9f503a42019-10-22 16:49:19 -0700745
746 if (service.guaranteeClient) {
Steven Morelandb8361902023-02-01 23:18:04 +0000747 if (!service.hasClients && !hasKernelReportedClients) {
Steven Moreland3e083b22023-01-26 00:46:30 +0000748 sendClientCallbackNotifications(serviceName, true,
749 "service is guaranteed to be in use");
Jon Spivack9f503a42019-10-22 16:49:19 -0700750 }
751
752 // guarantee is temporary
753 service.guaranteeClient = false;
754 }
755
Steven Morelandb8361902023-02-01 23:18:04 +0000756 // Regardless of this situation, we want to give this notification as soon as possible.
757 // This way, we have a chance of preventing further thrashing.
758 if (hasKernelReportedClients && !service.hasClients) {
759 sendClientCallbackNotifications(serviceName, true, "we now have a record of a client");
760 }
Steven Moreland66417652023-02-01 22:19:41 +0000761
Steven Morelandb8361902023-02-01 23:18:04 +0000762 // But limit rate of shutting down service.
763 if (isCalledOnInterval) {
764 if (!hasKernelReportedClients && service.hasClients) {
Steven Moreland3e083b22023-01-26 00:46:30 +0000765 sendClientCallbackNotifications(serviceName, false,
766 "we now have no record of a client");
Jon Spivackd9533c22020-01-27 22:19:22 +0000767 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700768 }
769
Steven Morelandb8361902023-02-01 23:18:04 +0000770 // May be different than 'hasKernelReportedClients'. We intentionally delay
771 // information about clients going away to reduce thrashing.
772 return service.hasClients;
Jon Spivack9f503a42019-10-22 16:49:19 -0700773}
774
Steven Moreland3e083b22023-01-26 00:46:30 +0000775void ServiceManager::sendClientCallbackNotifications(const std::string& serviceName,
776 bool hasClients, const char* context) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700777 auto serviceIt = mNameToService.find(serviceName);
778 if (serviceIt == mNameToService.end()) {
Steven Moreland3e083b22023-01-26 00:46:30 +0000779 ALOGW("sendClientCallbackNotifications could not find service %s when %s",
780 serviceName.c_str(), context);
Jon Spivack9f503a42019-10-22 16:49:19 -0700781 return;
782 }
783 Service& service = serviceIt->second;
784
Steven Morelandb8361902023-02-01 23:18:04 +0000785 CHECK_NE(hasClients, service.hasClients) << context;
Jon Spivack9f503a42019-10-22 16:49:19 -0700786
Steven Morelandb8361902023-02-01 23:18:04 +0000787 ALOGI("Notifying %s they %s (previously: %s) have clients when %s", serviceName.c_str(),
788 hasClients ? "do" : "don't", service.hasClients ? "do" : "don't", context);
Jon Spivack9f503a42019-10-22 16:49:19 -0700789
790 auto ccIt = mNameToClientCallback.find(serviceName);
791 CHECK(ccIt != mNameToClientCallback.end())
Steven Moreland3e083b22023-01-26 00:46:30 +0000792 << "sendClientCallbackNotifications could not find callbacks for service when "
793 << context;
Jon Spivack9f503a42019-10-22 16:49:19 -0700794
795 for (const auto& callback : ccIt->second) {
796 callback->onClients(service.binder, hasClients);
797 }
798
799 service.hasClients = hasClients;
800}
801
802Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
803 if (binder == nullptr) {
804 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
805 }
806
807 auto ctx = mAccess->getCallingContext();
808 if (!mAccess->canAdd(ctx, name)) {
809 return Status::fromExceptionCode(Status::EX_SECURITY);
810 }
811
812 auto serviceIt = mNameToService.find(name);
813 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000814 ALOGW("Tried to unregister %s, but that service wasn't registered to begin with.",
815 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700816 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
817 }
818
Steven Moreland7ee423b2022-09-24 03:52:08 +0000819 if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000820 ALOGW("Only a server can unregister itself (for %s)", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700821 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
822 }
823
824 sp<IBinder> storedBinder = serviceIt->second.binder;
825
826 if (binder != storedBinder) {
Pawan Wagh37526162022-09-29 21:55:26 +0000827 ALOGW("Tried to unregister %s, but a different service is registered under this name.",
828 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700829 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
830 }
831
Steven Morelandb8361902023-02-01 23:18:04 +0000832 // important because we don't have timer-based guarantees, we don't want to clear
833 // this
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700834 if (serviceIt->second.guaranteeClient) {
Pawan Wagh37526162022-09-29 21:55:26 +0000835 ALOGI("Tried to unregister %s, but there is about to be a client.", name.c_str());
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700836 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
837 }
838
Jon Spivack9f503a42019-10-22 16:49:19 -0700839 // - kernel driver will hold onto one refcount (during this transaction)
840 // - servicemanager has a refcount (guaranteed by this transaction)
Steven Morelandb8361902023-02-01 23:18:04 +0000841 constexpr size_t kKnownClients = 2;
842
843 if (handleServiceClientCallback(kKnownClients, name, false)) {
844 ALOGI("Tried to unregister %s, but there are clients.", name.c_str());
845
846 // Since we had a failed registration attempt, and the HIDL implementation of
847 // delaying service shutdown for multiple periods wasn't ported here... this may
848 // help reduce thrashing, but we should be able to remove it.
Jon Spivack620d2dc2020-03-06 13:58:01 -0800849 serviceIt->second.guaranteeClient = true;
Steven Morelandb8361902023-02-01 23:18:04 +0000850
Jon Spivack9f503a42019-10-22 16:49:19 -0700851 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
852 }
853
Steven Morelandb8361902023-02-01 23:18:04 +0000854 ALOGI("Unregistering %s", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700855 mNameToService.erase(name);
856
857 return Status::ok();
858}
859
Steven Moreland3ea43272021-01-28 22:49:28 +0000860Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
861 if (!mAccess->canList(mAccess->getCallingContext())) {
862 return Status::fromExceptionCode(Status::EX_SECURITY);
863 }
864
865 outReturn->reserve(mNameToService.size());
866 for (auto const& [name, service] : mNameToService) {
867 ServiceDebugInfo info;
868 info.name = name;
Steven Moreland7ee423b2022-09-24 03:52:08 +0000869 info.debugPid = service.ctx.debugPid;
Steven Moreland3ea43272021-01-28 22:49:28 +0000870
871 outReturn->push_back(std::move(info));
872 }
873
874 return Status::ok();
875}
876
Pawan Wagh243888e2022-09-20 19:37:35 +0000877void ServiceManager::clear() {
878 mNameToService.clear();
879 mNameToRegistrationCallback.clear();
880 mNameToClientCallback.clear();
881}
882
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700883} // namespace android