1 /* 2 * Copyright (C) 2016 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 <signal.h> 18 #include <sys/types.h> 19 #include <unistd.h> 20 21 #include <binder/Binder.h> 22 #include <binder/IBinder.h> 23 #include <binder/IServiceManager.h> 24 #include <binder/Parcel.h> 25 #include <binder/ProcessState.h> 26 27 #include <gtest/gtest.h> 28 29 #include "Allocator.h" 30 #include "Binder.h" 31 32 namespace android { 33 34 static const String16 service_name("test.libmemunreachable_binder"); 35 36 // Provides a service that will hold a strong reference to any remote binder 37 // object, so that the test can verify that a remote strong reference is 38 // visible to libmemunreachable. 39 class BinderService : public BBinder { 40 public: 41 BinderService() = default; 42 virtual ~BinderService() = default; 43 44 virtual status_t onTransact(uint32_t /*code*/, const Parcel& data, Parcel* reply, 45 uint32_t /*flags*/ = 0) { 46 reply->writeStrongBinder(ref); 47 ref = data.readStrongBinder(); 48 return 0; 49 } 50 51 private: 52 sp<IBinder> ref; 53 }; 54 55 class BinderObject : public BBinder { 56 public: 57 BinderObject() = default; 58 ~BinderObject() = default; 59 }; 60 61 // Forks a subprocess that registers a BinderService with the global binder 62 // servicemanager. Requires root permissions. 63 class ServiceProcess { 64 public: 65 ServiceProcess() : child_(0) {} 66 ~ServiceProcess() { Stop(); } 67 68 bool Run() { 69 pid_t ret = fork(); 70 if (ret < 0) { 71 return false; 72 } else if (ret == 0) { 73 // child 74 _exit(Service()); 75 } else { 76 // parent 77 child_ = ret; 78 return true; 79 } 80 } 81 82 bool Stop() { 83 if (child_ > 0) { 84 if (kill(child_, SIGTERM)) { 85 return false; 86 } 87 int status = 0; 88 if (TEMP_FAILURE_RETRY(waitpid(child_, &status, 0)) != child_) { 89 return false; 90 } 91 child_ = 0; 92 return WIFEXITED(status) && WEXITSTATUS(status) == 0; 93 } 94 95 return true; 96 } 97 98 int Service() { 99 sp<ProcessState> proc{ProcessState::self()}; 100 sp<IServiceManager> sm = defaultServiceManager(); 101 if (sm == nullptr) { 102 fprintf(stderr, "Failed to get service manager\n"); 103 return 1; 104 } 105 // This step requires root permissions 106 if (sm->addService(service_name, new BinderService()) != OK) { 107 fprintf(stderr, "Failed to add test service\n"); 108 return 1; 109 } 110 proc->startThreadPool(); 111 pause(); 112 return 0; 113 } 114 115 private: 116 pid_t child_; 117 }; 118 119 class MemunreachableBinderTest : public ::testing::Test { 120 protected: 121 ServiceProcess service_process_; 122 }; 123 124 // Tests that a local binder object with a remote strong reference is visible 125 // through the libmemunreachable BinderReferences interface, which uses the 126 // getBinderKernelReferences method in libbinder. Starts a BinderService 127 // through ServiceProcess as a remote service to hold the strong reference. 128 TEST_F(MemunreachableBinderTest, binder) { 129 ASSERT_EQ(static_cast<uid_t>(0), getuid()) << "This test must be run as root."; 130 131 ServiceProcess service_process; 132 ASSERT_TRUE(service_process.Run()); 133 134 sp<IServiceManager> sm = defaultServiceManager(); 135 ASSERT_TRUE(sm != nullptr); 136 137 // A small sleep allows the service to start, which 138 // prevents a longer sleep in getService. 139 usleep(100000); 140 141 sp<IBinder> service = sm->getService(service_name); 142 ASSERT_TRUE(service != nullptr); 143 144 sp<IBinder> binder{new BinderObject()}; 145 146 Parcel send; 147 Parcel reply; 148 149 send.writeStrongBinder(binder); 150 status_t rv = service->transact(0, send, &reply); 151 ASSERT_EQ(static_cast<status_t>(OK), rv); 152 153 Heap heap; 154 allocator::vector<uintptr_t> refs{heap}; 155 156 ASSERT_TRUE(BinderReferences(refs)); 157 158 bool found_ref = false; 159 for (auto ref : refs) { 160 if (ref == reinterpret_cast<uintptr_t>(binder.get())) { 161 found_ref = true; 162 } 163 } 164 165 ASSERT_TRUE(found_ref); 166 } 167 168 } // namespace android 169