blob: 2684f048f8afa3ca180cc9ca4649bc2e7f3e0a82 [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 Moreland86a17f82019-09-10 10:18:00 -070042#ifndef VENDORSERVICEMANAGER
Yifan Hong0a9b56e2021-11-30 16:45:40 -080043
Steven Moreland2e293aa2020-09-23 00:25:16 +000044struct ManifestWithDescription {
45 std::shared_ptr<const vintf::HalManifest> manifest;
46 const char* description;
47};
Yifan Hong0a9b56e2021-11-30 16:45:40 -080048static std::vector<ManifestWithDescription> GetManifestsWithDescription() {
49#ifdef __ANDROID_RECOVERY__
50 auto vintfObject = vintf::VintfObjectRecovery::GetInstance();
51 if (vintfObject == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000052 ALOGE("NULL VintfObjectRecovery!");
Yifan Hong0a9b56e2021-11-30 16:45:40 -080053 return {};
54 }
55 return {ManifestWithDescription{vintfObject->getRecoveryHalManifest(), "recovery"}};
56#else
57 auto vintfObject = vintf::VintfObject::GetInstance();
58 if (vintfObject == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000059 ALOGE("NULL VintfObject!");
Yifan Hong0a9b56e2021-11-30 16:45:40 -080060 return {};
61 }
62 return {ManifestWithDescription{vintfObject->getDeviceHalManifest(), "device"},
63 ManifestWithDescription{vintfObject->getFrameworkHalManifest(), "framework"}};
64#endif
65}
66
Steven Moreland2e293aa2020-09-23 00:25:16 +000067// func true -> stop search and forEachManifest will return true
68static bool forEachManifest(const std::function<bool(const ManifestWithDescription&)>& func) {
Yifan Hong0a9b56e2021-11-30 16:45:40 -080069 for (const ManifestWithDescription& mwd : GetManifestsWithDescription()) {
Steven Moreland2e293aa2020-09-23 00:25:16 +000070 if (mwd.manifest == nullptr) {
Pawan Wagh37526162022-09-29 21:55:26 +000071 ALOGE("NULL VINTF MANIFEST!: %s", mwd.description);
72 // note, we explicitly do not retry here, so that we can detect VINTF
73 // or other bugs (b/151696835)
74 continue;
Steven Moreland2e293aa2020-09-23 00:25:16 +000075 }
76 if (func(mwd)) return true;
77 }
78 return false;
79}
80
Steven Morelandedd4e072021-04-21 00:27:29 +000081struct AidlName {
82 std::string package;
83 std::string iface;
84 std::string instance;
Steven Moreland86a17f82019-09-10 10:18:00 -070085
Steven Morelandedd4e072021-04-21 00:27:29 +000086 static bool fill(const std::string& name, AidlName* aname) {
87 size_t firstSlash = name.find('/');
88 size_t lastDot = name.rfind('.', firstSlash);
89 if (firstSlash == std::string::npos || lastDot == std::string::npos) {
Pawan Wagh37526162022-09-29 21:55:26 +000090 ALOGE("VINTF HALs require names in the format type/instance (e.g. "
91 "some.package.foo.IFoo/default) but got: %s",
92 name.c_str());
Steven Morelandedd4e072021-04-21 00:27:29 +000093 return false;
94 }
95 aname->package = name.substr(0, lastDot);
96 aname->iface = name.substr(lastDot + 1, firstSlash - lastDot - 1);
97 aname->instance = name.substr(firstSlash + 1);
98 return true;
99 }
100};
101
102static bool isVintfDeclared(const std::string& name) {
103 AidlName aname;
104 if (!AidlName::fill(name, &aname)) return false;
105
106 bool found = forEachManifest([&](const ManifestWithDescription& mwd) {
107 if (mwd.manifest->hasAidlInstance(aname.package, aname.iface, aname.instance)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000108 ALOGI("Found %s in %s VINTF manifest.", name.c_str(), mwd.description);
Steven Morelandedd4e072021-04-21 00:27:29 +0000109 return true; // break
Steven Moreland86a17f82019-09-10 10:18:00 -0700110 }
Steven Moreland2e293aa2020-09-23 00:25:16 +0000111 return false; // continue
112 });
113
114 if (!found) {
115 // Although it is tested, explicitly rebuilding qualified name, in case it
116 // becomes something unexpected.
Pawan Wagh37526162022-09-29 21:55:26 +0000117 ALOGI("Could not find %s.%s/%s in the VINTF manifest.", aname.package.c_str(),
118 aname.iface.c_str(), aname.instance.c_str());
Steven Moreland86a17f82019-09-10 10:18:00 -0700119 }
Steven Moreland2edde8e2020-04-30 17:04:54 -0700120
Steven Moreland2e293aa2020-09-23 00:25:16 +0000121 return found;
122}
123
Steven Morelandedd4e072021-04-21 00:27:29 +0000124static std::optional<std::string> getVintfUpdatableApex(const std::string& name) {
125 AidlName aname;
126 if (!AidlName::fill(name, &aname)) return std::nullopt;
127
128 std::optional<std::string> updatableViaApex;
129
130 forEachManifest([&](const ManifestWithDescription& mwd) {
131 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
132 if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
133 if (manifestInstance.package() != aname.package) return true;
134 if (manifestInstance.interface() != aname.iface) return true;
135 if (manifestInstance.instance() != aname.instance) return true;
136 updatableViaApex = manifestInstance.updatableViaApex();
137 return false; // break (libvintf uses opposite convention)
138 });
139 return false; // continue
140 });
141
142 return updatableViaApex;
143}
144
Jooyung Han76944fe2022-10-25 17:02:45 +0900145static std::vector<std::string> getVintfUpdatableInstances(const std::string& apexName) {
146 std::vector<std::string> instances;
147
148 forEachManifest([&](const ManifestWithDescription& mwd) {
149 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
150 if (manifestInstance.format() == vintf::HalFormat::AIDL &&
151 manifestInstance.updatableViaApex().has_value() &&
152 manifestInstance.updatableViaApex().value() == apexName) {
153 std::string aname = manifestInstance.package() + "." +
154 manifestInstance.interface() + "/" + manifestInstance.instance();
155 instances.push_back(aname);
156 }
157 return false; // continue
158 });
159 return false; // continue
160 });
161
162 return instances;
163}
164
Devin Moore5e4c2f12021-09-09 22:36:33 +0000165static std::optional<ConnectionInfo> getVintfConnectionInfo(const std::string& name) {
166 AidlName aname;
167 if (!AidlName::fill(name, &aname)) return std::nullopt;
168
169 std::optional<std::string> ip;
170 std::optional<uint64_t> port;
171 forEachManifest([&](const ManifestWithDescription& mwd) {
172 mwd.manifest->forEachInstance([&](const auto& manifestInstance) {
173 if (manifestInstance.format() != vintf::HalFormat::AIDL) return true;
174 if (manifestInstance.package() != aname.package) return true;
175 if (manifestInstance.interface() != aname.iface) return true;
176 if (manifestInstance.instance() != aname.instance) return true;
177 ip = manifestInstance.ip();
178 port = manifestInstance.port();
179 return false; // break (libvintf uses opposite convention)
180 });
181 return false; // continue
182 });
183
184 if (ip.has_value() && port.has_value()) {
185 ConnectionInfo info;
186 info.ipAddress = *ip;
187 info.port = *port;
188 return std::make_optional<ConnectionInfo>(info);
189 } else {
190 return std::nullopt;
191 }
192}
193
Steven Moreland2e293aa2020-09-23 00:25:16 +0000194static std::vector<std::string> getVintfInstances(const std::string& interface) {
195 size_t lastDot = interface.rfind('.');
196 if (lastDot == std::string::npos) {
Pawan Wagh37526162022-09-29 21:55:26 +0000197 ALOGE("VINTF interfaces require names in Java package format (e.g. some.package.foo.IFoo) "
198 "but got: %s",
199 interface.c_str());
Steven Moreland2e293aa2020-09-23 00:25:16 +0000200 return {};
201 }
202 const std::string package = interface.substr(0, lastDot);
203 const std::string iface = interface.substr(lastDot+1);
204
205 std::vector<std::string> ret;
206 (void)forEachManifest([&](const ManifestWithDescription& mwd) {
207 auto instances = mwd.manifest->getAidlInstances(package, iface);
208 ret.insert(ret.end(), instances.begin(), instances.end());
209 return false; // continue
210 });
211
212 return ret;
Steven Moreland86a17f82019-09-10 10:18:00 -0700213}
Steven Morelandb82b8f82019-10-28 10:52:34 -0700214
215static bool meetsDeclarationRequirements(const sp<IBinder>& binder, const std::string& name) {
216 if (!Stability::requiresVintfDeclaration(binder)) {
217 return true;
218 }
219
220 return isVintfDeclared(name);
221}
Steven Moreland86a17f82019-09-10 10:18:00 -0700222#endif // !VENDORSERVICEMANAGER
223
Steven Morelandd13f08b2019-11-18 14:23:09 -0800224ServiceManager::ServiceManager(std::unique_ptr<Access>&& access) : mAccess(std::move(access)) {
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700225// TODO(b/151696835): reenable performance hack when we solve bug, since with
226// this hack and other fixes, it is unlikely we will see even an ephemeral
227// failure when the manifest parse fails. The goal is that the manifest will
228// be read incorrectly and cause the process trying to register a HAL to
229// fail. If this is in fact an early boot kernel contention issue, then we
230// will get no failure, and by its absence, be signalled to invest more
231// effort in re-adding this performance hack.
232// #ifndef VENDORSERVICEMANAGER
233// // can process these at any times, don't want to delay first VINTF client
234// std::thread([] {
235// vintf::VintfObject::GetDeviceHalManifest();
236// vintf::VintfObject::GetFrameworkHalManifest();
237// }).detach();
238// #endif // !VENDORSERVICEMANAGER
Steven Morelandd13f08b2019-11-18 14:23:09 -0800239}
Steven Moreland130242d2019-08-26 17:41:32 -0700240ServiceManager::~ServiceManager() {
241 // this should only happen in tests
242
Jon Spivackf288b1d2019-12-19 17:15:51 -0800243 for (const auto& [name, callbacks] : mNameToRegistrationCallback) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700244 CHECK(!callbacks.empty()) << name;
245 for (const auto& callback : callbacks) {
246 CHECK(callback != nullptr) << name;
247 }
248 }
249
Steven Moreland130242d2019-08-26 17:41:32 -0700250 for (const auto& [name, service] : mNameToService) {
251 CHECK(service.binder != nullptr) << name;
252 }
253}
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700254
255Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700256 *outBinder = tryGetService(name, true);
257 // returns ok regardless of result for legacy reasons
258 return Status::ok();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700259}
260
261Status ServiceManager::checkService(const std::string& name, sp<IBinder>* outBinder) {
Jon Spivack0d844302019-07-22 18:40:34 -0700262 *outBinder = tryGetService(name, false);
263 // returns ok regardless of result for legacy reasons
264 return Status::ok();
265}
266
267sp<IBinder> ServiceManager::tryGetService(const std::string& name, bool startIfNotFound) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700268 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700269
Jon Spivack0d844302019-07-22 18:40:34 -0700270 sp<IBinder> out;
Jon Spivack9f503a42019-10-22 16:49:19 -0700271 Service* service = nullptr;
Jon Spivack0d844302019-07-22 18:40:34 -0700272 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700273 service = &(it->second);
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700274
Jon Spivack9f503a42019-10-22 16:49:19 -0700275 if (!service->allowIsolated) {
Jon Spivack0d844302019-07-22 18:40:34 -0700276 uid_t appid = multiuser_get_app_id(ctx.uid);
277 bool isIsolated = appid >= AID_ISOLATED_START && appid <= AID_ISOLATED_END;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700278
Jon Spivack0d844302019-07-22 18:40:34 -0700279 if (isIsolated) {
280 return nullptr;
281 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700282 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700283 out = service->binder;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700284 }
285
Steven Morelanda9fe4742019-07-18 14:45:20 -0700286 if (!mAccess->canFind(ctx, name)) {
Jon Spivack0d844302019-07-22 18:40:34 -0700287 return nullptr;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700288 }
289
Jon Spivack0d844302019-07-22 18:40:34 -0700290 if (!out && startIfNotFound) {
291 tryStartService(name);
292 }
293
Jon Spivack9f503a42019-10-22 16:49:19 -0700294 if (out) {
295 // Setting this guarantee each time we hand out a binder ensures that the client-checking
296 // loop knows about the event even if the client immediately drops the service
297 service->guaranteeClient = true;
298 }
299
Jon Spivack0d844302019-07-22 18:40:34 -0700300 return out;
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700301}
302
Steven Moreland905e2e82019-07-17 11:05:45 -0700303bool isValidServiceName(const std::string& name) {
304 if (name.size() == 0) return false;
305 if (name.size() > 127) return false;
306
307 for (char c : name) {
Steven Morelandbb7951d2019-08-20 16:58:25 -0700308 if (c == '_' || c == '-' || c == '.' || c == '/') continue;
Steven Moreland905e2e82019-07-17 11:05:45 -0700309 if (c >= 'a' && c <= 'z') continue;
310 if (c >= 'A' && c <= 'Z') continue;
311 if (c >= '0' && c <= '9') continue;
312 return false;
313 }
314
315 return true;
316}
317
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700318Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700319 auto ctx = mAccess->getCallingContext();
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700320
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700321 if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000322 return Status::fromExceptionCode(Status::EX_SECURITY, "App UIDs cannot add services");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700323 }
324
Steven Morelanda9fe4742019-07-18 14:45:20 -0700325 if (!mAccess->canAdd(ctx, name)) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000326 return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700327 }
328
329 if (binder == nullptr) {
Steven Morelandac2d2852022-03-18 18:15:20 +0000330 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Null binder");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700331 }
332
Steven Moreland905e2e82019-07-17 11:05:45 -0700333 if (!isValidServiceName(name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000334 ALOGE("Invalid service name: %s", name.c_str());
Steven Morelandac2d2852022-03-18 18:15:20 +0000335 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "Invalid service name");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700336 }
337
Steven Moreland86a17f82019-09-10 10:18:00 -0700338#ifndef VENDORSERVICEMANAGER
339 if (!meetsDeclarationRequirements(binder, name)) {
340 // already logged
Steven Morelandac2d2852022-03-18 18:15:20 +0000341 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, "VINTF declaration error");
Steven Moreland86a17f82019-09-10 10:18:00 -0700342 }
343#endif // !VENDORSERVICEMANAGER
344
Steven Moreland88860b02019-08-12 14:24:14 -0700345 // implicitly unlinked when the binder is removed
Steven Morelandb0983182021-04-02 03:14:04 +0000346 if (binder->remoteBinder() != nullptr &&
347 binder->linkToDeath(sp<ServiceManager>::fromExisting(this)) != OK) {
Pawan Wagh37526162022-09-29 21:55:26 +0000348 ALOGE("Could not linkToDeath when adding %s", name.c_str());
Steven Morelandac2d2852022-03-18 18:15:20 +0000349 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, "linkToDeath failure");
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700350 }
351
Steven Moreland7ee423b2022-09-24 03:52:08 +0000352 auto it = mNameToService.find(name);
353 if (it != mNameToService.end()) {
354 const Service& existing = it->second;
355
356 // We could do better than this because if the other service dies, it
357 // may not have an entry here. However, this case is unlikely. We are
358 // only trying to detect when two different services are accidentally installed.
359
360 if (existing.ctx.uid != ctx.uid) {
Pawan Wagh37526162022-09-29 21:55:26 +0000361 ALOGW("Service '%s' originally registered from UID %u but it is now being registered "
362 "from UID %u. Multiple instances installed?",
363 name.c_str(), existing.ctx.uid, ctx.uid);
Steven Moreland7ee423b2022-09-24 03:52:08 +0000364 }
365
366 if (existing.ctx.sid != ctx.sid) {
Pawan Wagh37526162022-09-29 21:55:26 +0000367 ALOGW("Service '%s' originally registered from SID %s but it is now being registered "
368 "from SID %s. Multiple instances installed?",
369 name.c_str(), existing.ctx.sid.c_str(), ctx.sid.c_str());
Steven Moreland7ee423b2022-09-24 03:52:08 +0000370 }
371
Pawan Wagh37526162022-09-29 21:55:26 +0000372 ALOGI("Service '%s' originally registered from PID %d but it is being registered again "
373 "from PID %d. Bad state? Late death notification? Multiple instances installed?",
374 name.c_str(), existing.ctx.debugPid, ctx.debugPid);
Steven Moreland7ee423b2022-09-24 03:52:08 +0000375 }
376
Devin Moore05ffe522020-08-06 13:58:29 -0700377 // Overwrite the old service if it exists
Steven Moreland7ee423b2022-09-24 03:52:08 +0000378 mNameToService[name] = Service{
379 .binder = binder,
380 .allowIsolated = allowIsolated,
381 .dumpPriority = dumpPriority,
382 .ctx = ctx,
Devin Moore05ffe522020-08-06 13:58:29 -0700383 };
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700384
Steven Moreland7ee423b2022-09-24 03:52:08 +0000385 if (auto it = mNameToRegistrationCallback.find(name); it != mNameToRegistrationCallback.end()) {
Steven Moreland27cfab02019-08-12 14:34:16 -0700386 for (const sp<IServiceCallback>& cb : it->second) {
Devin Moore05ffe522020-08-06 13:58:29 -0700387 mNameToService[name].guaranteeClient = true;
Steven Moreland27cfab02019-08-12 14:34:16 -0700388 // permission checked in registerForNotifications
389 cb->onRegistration(name, binder);
390 }
391 }
392
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700393 return Status::ok();
394}
395
396Status ServiceManager::listServices(int32_t dumpPriority, std::vector<std::string>* outList) {
Steven Morelanda9fe4742019-07-18 14:45:20 -0700397 if (!mAccess->canList(mAccess->getCallingContext())) {
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700398 return Status::fromExceptionCode(Status::EX_SECURITY);
399 }
400
401 size_t toReserve = 0;
402 for (auto const& [name, service] : mNameToService) {
403 (void) name;
404
405 if (service.dumpPriority & dumpPriority) ++toReserve;
406 }
407
408 CHECK(outList->empty());
409
410 outList->reserve(toReserve);
411 for (auto const& [name, service] : mNameToService) {
412 (void) service;
413
414 if (service.dumpPriority & dumpPriority) {
415 outList->push_back(name);
416 }
417 }
418
419 return Status::ok();
420}
421
Steven Moreland27cfab02019-08-12 14:34:16 -0700422Status ServiceManager::registerForNotifications(
423 const std::string& name, const sp<IServiceCallback>& callback) {
424 auto ctx = mAccess->getCallingContext();
425
426 if (!mAccess->canFind(ctx, name)) {
427 return Status::fromExceptionCode(Status::EX_SECURITY);
428 }
429
430 if (!isValidServiceName(name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000431 ALOGE("Invalid service name: %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700432 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
433 }
434
435 if (callback == nullptr) {
436 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
437 }
438
Steven Morelandb0983182021-04-02 03:14:04 +0000439 if (OK !=
440 IInterface::asBinder(callback)->linkToDeath(
441 sp<ServiceManager>::fromExisting(this))) {
Pawan Wagh37526162022-09-29 21:55:26 +0000442 ALOGE("Could not linkToDeath when adding %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700443 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
444 }
445
Jon Spivackf288b1d2019-12-19 17:15:51 -0800446 mNameToRegistrationCallback[name].push_back(callback);
Steven Moreland27cfab02019-08-12 14:34:16 -0700447
448 if (auto it = mNameToService.find(name); it != mNameToService.end()) {
449 const sp<IBinder>& binder = it->second.binder;
450
451 // never null if an entry exists
452 CHECK(binder != nullptr) << name;
453 callback->onRegistration(name, binder);
454 }
455
456 return Status::ok();
457}
458Status ServiceManager::unregisterForNotifications(
459 const std::string& name, const sp<IServiceCallback>& callback) {
460 auto ctx = mAccess->getCallingContext();
461
462 if (!mAccess->canFind(ctx, name)) {
463 return Status::fromExceptionCode(Status::EX_SECURITY);
464 }
465
466 bool found = false;
467
Jon Spivackf288b1d2019-12-19 17:15:51 -0800468 auto it = mNameToRegistrationCallback.find(name);
469 if (it != mNameToRegistrationCallback.end()) {
470 removeRegistrationCallback(IInterface::asBinder(callback), &it, &found);
Steven Moreland27cfab02019-08-12 14:34:16 -0700471 }
472
473 if (!found) {
Pawan Wagh37526162022-09-29 21:55:26 +0000474 ALOGE("Trying to unregister callback, but none exists %s", name.c_str());
Steven Moreland27cfab02019-08-12 14:34:16 -0700475 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
476 }
477
478 return Status::ok();
479}
480
Steven Morelandb82b8f82019-10-28 10:52:34 -0700481Status ServiceManager::isDeclared(const std::string& name, bool* outReturn) {
482 auto ctx = mAccess->getCallingContext();
483
484 if (!mAccess->canFind(ctx, name)) {
485 return Status::fromExceptionCode(Status::EX_SECURITY);
486 }
487
488 *outReturn = false;
489
490#ifndef VENDORSERVICEMANAGER
491 *outReturn = isVintfDeclared(name);
492#endif
493 return Status::ok();
494}
495
Steven Moreland2e293aa2020-09-23 00:25:16 +0000496binder::Status ServiceManager::getDeclaredInstances(const std::string& interface, std::vector<std::string>* outReturn) {
497 auto ctx = mAccess->getCallingContext();
498
499 std::vector<std::string> allInstances;
500#ifndef VENDORSERVICEMANAGER
501 allInstances = getVintfInstances(interface);
502#endif
503
504 outReturn->clear();
505
506 for (const std::string& instance : allInstances) {
Steven Moreland2e293aa2020-09-23 00:25:16 +0000507 if (mAccess->canFind(ctx, interface + "/" + instance)) {
508 outReturn->push_back(instance);
509 }
510 }
511
512 if (outReturn->size() == 0 && allInstances.size() != 0) {
513 return Status::fromExceptionCode(Status::EX_SECURITY);
514 }
515
516 return Status::ok();
517}
518
Steven Morelandedd4e072021-04-21 00:27:29 +0000519Status ServiceManager::updatableViaApex(const std::string& name,
520 std::optional<std::string>* outReturn) {
521 auto ctx = mAccess->getCallingContext();
522
523 if (!mAccess->canFind(ctx, name)) {
524 return Status::fromExceptionCode(Status::EX_SECURITY);
525 }
526
527 *outReturn = std::nullopt;
528
529#ifndef VENDORSERVICEMANAGER
530 *outReturn = getVintfUpdatableApex(name);
531#endif
532 return Status::ok();
533}
534
Jooyung Han76944fe2022-10-25 17:02:45 +0900535Status ServiceManager::getUpdatableNames([[maybe_unused]] const std::string& apexName,
536 std::vector<std::string>* outReturn) {
537 auto ctx = mAccess->getCallingContext();
538
539 std::vector<std::string> apexUpdatableInstances;
540#ifndef VENDORSERVICEMANAGER
541 apexUpdatableInstances = getVintfUpdatableInstances(apexName);
542#endif
543
544 outReturn->clear();
545
546 for (const std::string& instance : apexUpdatableInstances) {
547 if (mAccess->canFind(ctx, instance)) {
548 outReturn->push_back(instance);
549 }
550 }
551
552 if (outReturn->size() == 0 && apexUpdatableInstances.size() != 0) {
553 return Status::fromExceptionCode(Status::EX_SECURITY, "SELinux denial");
554 }
555
556 return Status::ok();
557}
558
Devin Moore5e4c2f12021-09-09 22:36:33 +0000559Status ServiceManager::getConnectionInfo(const std::string& name,
560 std::optional<ConnectionInfo>* outReturn) {
561 auto ctx = mAccess->getCallingContext();
562
563 if (!mAccess->canFind(ctx, name)) {
564 return Status::fromExceptionCode(Status::EX_SECURITY);
565 }
566
567 *outReturn = std::nullopt;
568
569#ifndef VENDORSERVICEMANAGER
570 *outReturn = getVintfConnectionInfo(name);
571#endif
572 return Status::ok();
573}
574
Jon Spivackf288b1d2019-12-19 17:15:51 -0800575void ServiceManager::removeRegistrationCallback(const wp<IBinder>& who,
576 ServiceCallbackMap::iterator* it,
Steven Moreland27cfab02019-08-12 14:34:16 -0700577 bool* found) {
578 std::vector<sp<IServiceCallback>>& listeners = (*it)->second;
579
580 for (auto lit = listeners.begin(); lit != listeners.end();) {
581 if (IInterface::asBinder(*lit) == who) {
582 if(found) *found = true;
583 lit = listeners.erase(lit);
584 } else {
585 ++lit;
586 }
587 }
588
589 if (listeners.empty()) {
Jon Spivackf288b1d2019-12-19 17:15:51 -0800590 *it = mNameToRegistrationCallback.erase(*it);
Steven Moreland27cfab02019-08-12 14:34:16 -0700591 } else {
Jon Spivacke223f082019-11-19 16:21:20 -0800592 (*it)++;
Steven Moreland27cfab02019-08-12 14:34:16 -0700593 }
594}
595
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700596void ServiceManager::binderDied(const wp<IBinder>& who) {
597 for (auto it = mNameToService.begin(); it != mNameToService.end();) {
598 if (who == it->second.binder) {
599 it = mNameToService.erase(it);
600 } else {
601 ++it;
602 }
603 }
Steven Moreland27cfab02019-08-12 14:34:16 -0700604
Jon Spivackf288b1d2019-12-19 17:15:51 -0800605 for (auto it = mNameToRegistrationCallback.begin(); it != mNameToRegistrationCallback.end();) {
606 removeRegistrationCallback(who, &it, nullptr /*found*/);
Steven Moreland27cfab02019-08-12 14:34:16 -0700607 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700608
609 for (auto it = mNameToClientCallback.begin(); it != mNameToClientCallback.end();) {
610 removeClientCallback(who, &it);
611 }
Steven Moreland80e1e6d2019-06-21 12:35:59 -0700612}
613
Jon Spivack0d844302019-07-22 18:40:34 -0700614void ServiceManager::tryStartService(const std::string& name) {
615 ALOGI("Since '%s' could not be found, trying to start it as a lazy AIDL service",
616 name.c_str());
617
618 std::thread([=] {
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000619 if (!base::SetProperty("ctl.interface_start", "aidl/" + name)) {
Pawan Wagh37526162022-09-29 21:55:26 +0000620 ALOGI("Tried to start aidl service %s as a lazy service, but was unable to. Usually "
621 "this happens when a "
622 "service is not installed, but if the service is intended to be used as a "
623 "lazy service, then it may be configured incorrectly.",
624 name.c_str());
Steven Morelandbfe9fba2021-04-27 18:39:57 +0000625 }
Jon Spivack0d844302019-07-22 18:40:34 -0700626 }).detach();
627}
628
Jon Spivack9f503a42019-10-22 16:49:19 -0700629Status ServiceManager::registerClientCallback(const std::string& name, const sp<IBinder>& service,
630 const sp<IClientCallback>& cb) {
631 if (cb == nullptr) {
632 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
633 }
634
635 auto ctx = mAccess->getCallingContext();
636 if (!mAccess->canAdd(ctx, name)) {
637 return Status::fromExceptionCode(Status::EX_SECURITY);
638 }
639
640 auto serviceIt = mNameToService.find(name);
641 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000642 ALOGE("Could not add callback for nonexistent service: %s", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700643 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
644 }
645
Steven Moreland7ee423b2022-09-24 03:52:08 +0000646 if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000647 ALOGW("Only a server can register for client callbacks (for %s)", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700648 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
649 }
650
651 if (serviceIt->second.binder != service) {
Pawan Wagh37526162022-09-29 21:55:26 +0000652 ALOGW("Tried to register client callback for %s but a different service is registered "
653 "under this name.",
654 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700655 return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
656 }
657
Steven Morelandb0983182021-04-02 03:14:04 +0000658 if (OK !=
659 IInterface::asBinder(cb)->linkToDeath(sp<ServiceManager>::fromExisting(this))) {
Pawan Wagh37526162022-09-29 21:55:26 +0000660 ALOGE("Could not linkToDeath when adding client callback for %s", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700661 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
662 }
663
664 mNameToClientCallback[name].push_back(cb);
665
666 return Status::ok();
667}
668
669void ServiceManager::removeClientCallback(const wp<IBinder>& who,
670 ClientCallbackMap::iterator* it) {
671 std::vector<sp<IClientCallback>>& listeners = (*it)->second;
672
673 for (auto lit = listeners.begin(); lit != listeners.end();) {
674 if (IInterface::asBinder(*lit) == who) {
675 lit = listeners.erase(lit);
676 } else {
677 ++lit;
678 }
679 }
680
681 if (listeners.empty()) {
682 *it = mNameToClientCallback.erase(*it);
683 } else {
684 (*it)++;
685 }
686}
687
688ssize_t ServiceManager::Service::getNodeStrongRefCount() {
Steven Morelandb0983182021-04-02 03:14:04 +0000689 sp<BpBinder> bpBinder = sp<BpBinder>::fromExisting(binder->remoteBinder());
Jon Spivack9f503a42019-10-22 16:49:19 -0700690 if (bpBinder == nullptr) return -1;
691
Steven Morelande8393882020-12-18 02:27:20 +0000692 return ProcessState::self()->getStrongRefCountForNode(bpBinder);
Jon Spivack9f503a42019-10-22 16:49:19 -0700693}
694
695void ServiceManager::handleClientCallbacks() {
696 for (const auto& [name, service] : mNameToService) {
Jon Spivackd9533c22020-01-27 22:19:22 +0000697 handleServiceClientCallback(name, true);
Jon Spivack9f503a42019-10-22 16:49:19 -0700698 }
699}
700
Jon Spivackd9533c22020-01-27 22:19:22 +0000701ssize_t ServiceManager::handleServiceClientCallback(const std::string& serviceName,
702 bool isCalledOnInterval) {
Jon Spivack9f503a42019-10-22 16:49:19 -0700703 auto serviceIt = mNameToService.find(serviceName);
704 if (serviceIt == mNameToService.end() || mNameToClientCallback.count(serviceName) < 1) {
705 return -1;
706 }
707
708 Service& service = serviceIt->second;
709 ssize_t count = service.getNodeStrongRefCount();
710
711 // binder driver doesn't support this feature
712 if (count == -1) return count;
713
714 bool hasClients = count > 1; // this process holds a strong count
715
716 if (service.guaranteeClient) {
717 // we have no record of this client
718 if (!service.hasClients && !hasClients) {
719 sendClientCallbackNotifications(serviceName, true);
720 }
721
722 // guarantee is temporary
723 service.guaranteeClient = false;
724 }
725
Jon Spivackd9533c22020-01-27 22:19:22 +0000726 // only send notifications if this was called via the interval checking workflow
727 if (isCalledOnInterval) {
728 if (hasClients && !service.hasClients) {
729 // client was retrieved in some other way
730 sendClientCallbackNotifications(serviceName, true);
731 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700732
Jon Spivackd9533c22020-01-27 22:19:22 +0000733 // there are no more clients, but the callback has not been called yet
734 if (!hasClients && service.hasClients) {
735 sendClientCallbackNotifications(serviceName, false);
736 }
Jon Spivack9f503a42019-10-22 16:49:19 -0700737 }
738
739 return count;
740}
741
742void ServiceManager::sendClientCallbackNotifications(const std::string& serviceName, bool hasClients) {
743 auto serviceIt = mNameToService.find(serviceName);
744 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000745 ALOGW("sendClientCallbackNotifications could not find service %s", serviceName.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700746 return;
747 }
748 Service& service = serviceIt->second;
749
750 CHECK(hasClients != service.hasClients) << "Record shows: " << service.hasClients
751 << " so we can't tell clients again that we have client: " << hasClients;
752
Pawan Wagh37526162022-09-29 21:55:26 +0000753 ALOGI("Notifying %s they have clients: %d", serviceName.c_str(), hasClients);
Jon Spivack9f503a42019-10-22 16:49:19 -0700754
755 auto ccIt = mNameToClientCallback.find(serviceName);
756 CHECK(ccIt != mNameToClientCallback.end())
757 << "sendClientCallbackNotifications could not find callbacks for service ";
758
759 for (const auto& callback : ccIt->second) {
760 callback->onClients(service.binder, hasClients);
761 }
762
763 service.hasClients = hasClients;
764}
765
766Status ServiceManager::tryUnregisterService(const std::string& name, const sp<IBinder>& binder) {
767 if (binder == nullptr) {
768 return Status::fromExceptionCode(Status::EX_NULL_POINTER);
769 }
770
771 auto ctx = mAccess->getCallingContext();
772 if (!mAccess->canAdd(ctx, name)) {
773 return Status::fromExceptionCode(Status::EX_SECURITY);
774 }
775
776 auto serviceIt = mNameToService.find(name);
777 if (serviceIt == mNameToService.end()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000778 ALOGW("Tried to unregister %s, but that service wasn't registered to begin with.",
779 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700780 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
781 }
782
Steven Moreland7ee423b2022-09-24 03:52:08 +0000783 if (serviceIt->second.ctx.debugPid != IPCThreadState::self()->getCallingPid()) {
Pawan Wagh37526162022-09-29 21:55:26 +0000784 ALOGW("Only a server can unregister itself (for %s)", name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700785 return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION);
786 }
787
788 sp<IBinder> storedBinder = serviceIt->second.binder;
789
790 if (binder != storedBinder) {
Pawan Wagh37526162022-09-29 21:55:26 +0000791 ALOGW("Tried to unregister %s, but a different service is registered under this name.",
792 name.c_str());
Jon Spivack9f503a42019-10-22 16:49:19 -0700793 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
794 }
795
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700796 if (serviceIt->second.guaranteeClient) {
Pawan Wagh37526162022-09-29 21:55:26 +0000797 ALOGI("Tried to unregister %s, but there is about to be a client.", name.c_str());
Jon Spivack0f18f2c2020-03-13 20:45:18 -0700798 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
799 }
800
Jon Spivackd9533c22020-01-27 22:19:22 +0000801 int clients = handleServiceClientCallback(name, false);
Jon Spivack9f503a42019-10-22 16:49:19 -0700802
803 // clients < 0: feature not implemented or other error. Assume clients.
804 // Otherwise:
805 // - kernel driver will hold onto one refcount (during this transaction)
806 // - servicemanager has a refcount (guaranteed by this transaction)
807 // So, if clients > 2, then at least one other service on the system must hold a refcount.
808 if (clients < 0 || clients > 2) {
809 // client callbacks are either disabled or there are other clients
Pawan Wagh37526162022-09-29 21:55:26 +0000810 ALOGI("Tried to unregister %s, but there are clients: %d", name.c_str(), clients);
Jon Spivack620d2dc2020-03-06 13:58:01 -0800811 // Set this flag to ensure the clients are acknowledged in the next callback
812 serviceIt->second.guaranteeClient = true;
Jon Spivack9f503a42019-10-22 16:49:19 -0700813 return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE);
814 }
815
816 mNameToService.erase(name);
817
818 return Status::ok();
819}
820
Steven Moreland3ea43272021-01-28 22:49:28 +0000821Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
822 if (!mAccess->canList(mAccess->getCallingContext())) {
823 return Status::fromExceptionCode(Status::EX_SECURITY);
824 }
825
826 outReturn->reserve(mNameToService.size());
827 for (auto const& [name, service] : mNameToService) {
828 ServiceDebugInfo info;
829 info.name = name;
Steven Moreland7ee423b2022-09-24 03:52:08 +0000830 info.debugPid = service.ctx.debugPid;
Steven Moreland3ea43272021-01-28 22:49:28 +0000831
832 outReturn->push_back(std::move(info));
833 }
834
835 return Status::ok();
836}
837
Pawan Wagh243888e2022-09-20 19:37:35 +0000838void ServiceManager::clear() {
839 mNameToService.clear();
840 mNameToRegistrationCallback.clear();
841 mNameToClientCallback.clear();
842}
843
Steven Moreland8d0c9a72020-04-30 16:51:56 -0700844} // namespace android