| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 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 |  | 
 | 17 | #include <binder/ProcessState.h> | 
 | 18 | #include <cutils/android_filesystem_config.h> | 
 | 19 | #include <gtest/gtest.h> | 
 | 20 | #include <gmock/gmock.h> | 
 | 21 |  | 
 | 22 | #include "Access.h" | 
 | 23 | #include "ServiceManager.h" | 
 | 24 |  | 
 | 25 | using android::sp; | 
 | 26 | using android::Access; | 
 | 27 | using android::IBinder; | 
 | 28 | using android::ServiceManager; | 
 | 29 | using android::os::IServiceManager; | 
 | 30 | using testing::_; | 
 | 31 | using testing::ElementsAre; | 
 | 32 | using testing::NiceMock; | 
 | 33 | using testing::Return; | 
 | 34 |  | 
 | 35 | static sp<IBinder> getBinder() { | 
 | 36 |     // It doesn't matter what remote binder it is, we just need one so that linkToDeath will work. | 
 | 37 |     // The context manager (servicemanager) is easy to get and is in another process. | 
 | 38 |     return android::ProcessState::self()->getContextObject(nullptr); | 
 | 39 | } | 
 | 40 |  | 
 | 41 | class MockAccess : public Access { | 
 | 42 | public: | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 43 |     MOCK_METHOD0(getCallingContext, CallingContext()); | 
 | 44 |     MOCK_METHOD2(canAdd, bool(const CallingContext&, const std::string& name)); | 
 | 45 |     MOCK_METHOD2(canFind, bool(const CallingContext&, const std::string& name)); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 46 |     MOCK_METHOD1(canList, bool(const CallingContext&)); | 
 | 47 | }; | 
 | 48 |  | 
 | 49 | static sp<ServiceManager> getPermissiveServiceManager() { | 
 | 50 |     std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); | 
 | 51 |  | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 52 |     ON_CALL(*access, getCallingContext()).WillByDefault(Return(Access::CallingContext{})); | 
 | 53 |     ON_CALL(*access, canAdd(_, _)).WillByDefault(Return(true)); | 
 | 54 |     ON_CALL(*access, canFind(_, _)).WillByDefault(Return(true)); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 55 |     ON_CALL(*access, canList(_)).WillByDefault(Return(true)); | 
 | 56 |  | 
 | 57 |     sp<ServiceManager> sm = new ServiceManager(std::move(access)); | 
 | 58 |     return sm; | 
 | 59 | } | 
 | 60 |  | 
 | 61 | TEST(AddService, HappyHappy) { | 
 | 62 |     auto sm = getPermissiveServiceManager(); | 
 | 63 |     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 64 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 65 | } | 
 | 66 |  | 
 | 67 | TEST(AddService, EmptyNameDisallowed) { | 
 | 68 |     auto sm = getPermissiveServiceManager(); | 
 | 69 |     EXPECT_FALSE(sm->addService("", getBinder(), false /*allowIsolated*/, | 
 | 70 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 71 | } | 
 | 72 |  | 
 | 73 | TEST(AddService, JustShortEnoughServiceNameHappy) { | 
 | 74 |     auto sm = getPermissiveServiceManager(); | 
 | 75 |     EXPECT_TRUE(sm->addService(std::string(127, 'a'), getBinder(), false /*allowIsolated*/, | 
 | 76 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 77 | } | 
 | 78 |  | 
 | 79 | TEST(AddService, TooLongNameDisallowed) { | 
 | 80 |     auto sm = getPermissiveServiceManager(); | 
 | 81 |     EXPECT_FALSE(sm->addService(std::string(128, 'a'), getBinder(), false /*allowIsolated*/, | 
 | 82 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 83 | } | 
 | 84 |  | 
| Steven Moreland | 905e2e8 | 2019-07-17 11:05:45 -0700 | [diff] [blame] | 85 | TEST(AddService, WeirdCharactersDisallowed) { | 
 | 86 |     auto sm = getPermissiveServiceManager(); | 
 | 87 |     EXPECT_FALSE(sm->addService("happy$foo$foo", getBinder(), false /*allowIsolated*/, | 
 | 88 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 89 | } | 
 | 90 |  | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 91 | TEST(AddService, AddNullServiceDisallowed) { | 
 | 92 |     auto sm = getPermissiveServiceManager(); | 
 | 93 |     EXPECT_FALSE(sm->addService("foo", nullptr, false /*allowIsolated*/, | 
 | 94 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 95 | } | 
 | 96 |  | 
 | 97 | TEST(AddService, AddDisallowedFromApp) { | 
 | 98 |     for (uid_t uid : { AID_APP_START, AID_APP_START + 1, AID_APP_END }) { | 
 | 99 |         std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 100 |         EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{ | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 101 |             .debugPid = 1337, | 
 | 102 |             .uid = uid, | 
 | 103 |         })); | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 104 |         EXPECT_CALL(*access, canAdd(_, _)).Times(0); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 105 |         sp<ServiceManager> sm = new ServiceManager(std::move(access)); | 
 | 106 |  | 
 | 107 |         EXPECT_FALSE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 108 |             IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 109 |     } | 
 | 110 |  | 
 | 111 | } | 
 | 112 |  | 
 | 113 | TEST(AddService, HappyOverExistingService) { | 
 | 114 |     auto sm = getPermissiveServiceManager(); | 
 | 115 |     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 116 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 117 |     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 118 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 119 | } | 
 | 120 |  | 
 | 121 | TEST(AddService, NoPermissions) { | 
 | 122 |     std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); | 
 | 123 |  | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 124 |     EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{})); | 
 | 125 |     EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(false)); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 126 |  | 
 | 127 |     sp<ServiceManager> sm = new ServiceManager(std::move(access)); | 
 | 128 |  | 
 | 129 |     EXPECT_FALSE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 130 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 131 | } | 
 | 132 |  | 
 | 133 | TEST(GetService, HappyHappy) { | 
 | 134 |     auto sm = getPermissiveServiceManager(); | 
 | 135 |     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 136 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 137 |  | 
 | 138 |     sp<IBinder> out; | 
 | 139 |     EXPECT_TRUE(sm->getService("foo", &out).isOk()); | 
 | 140 |     EXPECT_EQ(getBinder(), out); | 
 | 141 | } | 
 | 142 |  | 
 | 143 | TEST(GetService, NonExistant) { | 
 | 144 |     auto sm = getPermissiveServiceManager(); | 
 | 145 |  | 
 | 146 |     sp<IBinder> out; | 
 | 147 |     EXPECT_TRUE(sm->getService("foo", &out).isOk()); | 
 | 148 |     EXPECT_EQ(nullptr, out.get()); | 
 | 149 | } | 
 | 150 |  | 
 | 151 | TEST(GetService, NoPermissionsForGettingService) { | 
 | 152 |     std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); | 
 | 153 |  | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 154 |     EXPECT_CALL(*access, getCallingContext()).WillRepeatedly(Return(Access::CallingContext{})); | 
 | 155 |     EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true)); | 
 | 156 |     EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(false)); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 157 |  | 
 | 158 |     sp<ServiceManager> sm = new ServiceManager(std::move(access)); | 
 | 159 |  | 
 | 160 |     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 161 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 162 |  | 
 | 163 |     sp<IBinder> out; | 
 | 164 |     // returns nullptr but has OK status for legacy compatibility | 
 | 165 |     EXPECT_TRUE(sm->getService("foo", &out).isOk()); | 
 | 166 |     EXPECT_EQ(nullptr, out.get()); | 
 | 167 | } | 
 | 168 |  | 
 | 169 | TEST(GetService, AllowedFromIsolated) { | 
 | 170 |     std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); | 
 | 171 |  | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 172 |     EXPECT_CALL(*access, getCallingContext()) | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 173 |         // something adds it | 
 | 174 |         .WillOnce(Return(Access::CallingContext{})) | 
 | 175 |         // next call is from isolated app | 
 | 176 |         .WillOnce(Return(Access::CallingContext{ | 
 | 177 |             .uid = AID_ISOLATED_START, | 
 | 178 |         })); | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 179 |     EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true)); | 
 | 180 |     EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true)); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 181 |  | 
 | 182 |     sp<ServiceManager> sm = new ServiceManager(std::move(access)); | 
 | 183 |  | 
 | 184 |     EXPECT_TRUE(sm->addService("foo", getBinder(), true /*allowIsolated*/, | 
 | 185 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 186 |  | 
 | 187 |     sp<IBinder> out; | 
 | 188 |     EXPECT_TRUE(sm->getService("foo", &out).isOk()); | 
 | 189 |     EXPECT_EQ(getBinder(), out.get()); | 
 | 190 | } | 
 | 191 |  | 
 | 192 | TEST(GetService, NotAllowedFromIsolated) { | 
 | 193 |     std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); | 
 | 194 |  | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 195 |     EXPECT_CALL(*access, getCallingContext()) | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 196 |         // something adds it | 
 | 197 |         .WillOnce(Return(Access::CallingContext{})) | 
 | 198 |         // next call is from isolated app | 
 | 199 |         .WillOnce(Return(Access::CallingContext{ | 
 | 200 |             .uid = AID_ISOLATED_START, | 
 | 201 |         })); | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 202 |     EXPECT_CALL(*access, canAdd(_, _)).WillOnce(Return(true)); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 203 |  | 
 | 204 |     // TODO(b/136023468): when security check is first, this should be called first | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 205 |     // EXPECT_CALL(*access, canFind(_, _)).WillOnce(Return(true)); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 206 |  | 
 | 207 |     sp<ServiceManager> sm = new ServiceManager(std::move(access)); | 
 | 208 |  | 
 | 209 |     EXPECT_TRUE(sm->addService("foo", getBinder(), false /*allowIsolated*/, | 
 | 210 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 211 |  | 
 | 212 |     sp<IBinder> out; | 
 | 213 |     // returns nullptr but has OK status for legacy compatibility | 
 | 214 |     EXPECT_TRUE(sm->getService("foo", &out).isOk()); | 
 | 215 |     EXPECT_EQ(nullptr, out.get()); | 
 | 216 | } | 
 | 217 |  | 
 | 218 | TEST(ListServices, NoPermissions) { | 
 | 219 |     std::unique_ptr<MockAccess> access = std::make_unique<NiceMock<MockAccess>>(); | 
 | 220 |  | 
| Steven Moreland | a9fe474 | 2019-07-18 14:45:20 -0700 | [diff] [blame] | 221 |     EXPECT_CALL(*access, getCallingContext()).WillOnce(Return(Access::CallingContext{})); | 
| Steven Moreland | 80e1e6d | 2019-06-21 12:35:59 -0700 | [diff] [blame] | 222 |     EXPECT_CALL(*access, canList(_)).WillOnce(Return(false)); | 
 | 223 |  | 
 | 224 |     sp<ServiceManager> sm = new ServiceManager(std::move(access)); | 
 | 225 |  | 
 | 226 |     std::vector<std::string> out; | 
 | 227 |     EXPECT_FALSE(sm->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL, &out).isOk()); | 
 | 228 |     EXPECT_TRUE(out.empty()); | 
 | 229 | } | 
 | 230 |  | 
 | 231 | TEST(ListServices, AllServices) { | 
 | 232 |     auto sm = getPermissiveServiceManager(); | 
 | 233 |  | 
 | 234 |     EXPECT_TRUE(sm->addService("sd", getBinder(), false /*allowIsolated*/, | 
 | 235 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 236 |     EXPECT_TRUE(sm->addService("sc", getBinder(), false /*allowIsolated*/, | 
 | 237 |         IServiceManager::DUMP_FLAG_PRIORITY_NORMAL).isOk()); | 
 | 238 |     EXPECT_TRUE(sm->addService("sb", getBinder(), false /*allowIsolated*/, | 
 | 239 |         IServiceManager::DUMP_FLAG_PRIORITY_HIGH).isOk()); | 
 | 240 |     EXPECT_TRUE(sm->addService("sa", getBinder(), false /*allowIsolated*/, | 
 | 241 |         IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL).isOk()); | 
 | 242 |  | 
 | 243 |     std::vector<std::string> out; | 
 | 244 |     EXPECT_TRUE(sm->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL, &out).isOk()); | 
 | 245 |  | 
 | 246 |     // all there and in the right order | 
 | 247 |     EXPECT_THAT(out, ElementsAre("sa", "sb", "sc", "sd")); | 
 | 248 | } | 
 | 249 |  | 
 | 250 | TEST(ListServices, CriticalServices) { | 
 | 251 |     auto sm = getPermissiveServiceManager(); | 
 | 252 |  | 
 | 253 |     EXPECT_TRUE(sm->addService("sd", getBinder(), false /*allowIsolated*/, | 
 | 254 |         IServiceManager::DUMP_FLAG_PRIORITY_DEFAULT).isOk()); | 
 | 255 |     EXPECT_TRUE(sm->addService("sc", getBinder(), false /*allowIsolated*/, | 
 | 256 |         IServiceManager::DUMP_FLAG_PRIORITY_NORMAL).isOk()); | 
 | 257 |     EXPECT_TRUE(sm->addService("sb", getBinder(), false /*allowIsolated*/, | 
 | 258 |         IServiceManager::DUMP_FLAG_PRIORITY_HIGH).isOk()); | 
 | 259 |     EXPECT_TRUE(sm->addService("sa", getBinder(), false /*allowIsolated*/, | 
 | 260 |         IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL).isOk()); | 
 | 261 |  | 
 | 262 |     std::vector<std::string> out; | 
 | 263 |     EXPECT_TRUE(sm->listServices(IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL, &out).isOk()); | 
 | 264 |  | 
 | 265 |     // all there and in the right order | 
 | 266 |     EXPECT_THAT(out, ElementsAre("sa")); | 
 | 267 | } |