cmd.cpp revision c21bc9afe403f52c189d2d6b79dedaf9dce6217b
123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn/* 223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * Copyright (C) 2015 The Android Open Source Project 323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * 423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License"); 523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * you may not use this file except in compliance with the License. 623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * You may obtain a copy of the License at 723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * 823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * http://www.apache.org/licenses/LICENSE-2.0 923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * 1023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * Unless required by applicable law or agreed to in writing, software 1123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS, 1223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * See the License for the specific language governing permissions and 1423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn * limitations under the License. 1523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn */ 1623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 1723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#define LOG_TAG "cmd" 1823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 1923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <utils/Log.h> 2023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/Parcel.h> 2123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/ProcessState.h> 2223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/IResultReceiver.h> 2323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/IServiceManager.h> 241941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include <binder/IShellCallback.h> 2523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <binder/TextOutput.h> 263d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#include <utils/Condition.h> 273d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#include <utils/Mutex.h> 2823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <utils/Vector.h> 2923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 3023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <getopt.h> 3123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <stdlib.h> 3223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <stdio.h> 3323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <string.h> 3423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <unistd.h> 351941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include <fcntl.h> 3623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn#include <sys/time.h> 371941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include <errno.h> 381941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 391941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include "selinux/selinux.h" 401941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include "selinux/android.h" 411941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 421941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn#include <UniquePtr.h> 4323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 443d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#define DEBUG 0 453d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 4623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornusing namespace android; 4723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 4823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornstatic int sort_func(const String16* lhs, const String16* rhs) 4923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn{ 5023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return lhs->compare(*rhs); 5123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn} 5223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 531941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackbornstruct SecurityContext_Delete { 541941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn void operator()(security_context_t p) const { 551941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn freecon(p); 561941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 571941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn}; 581941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborntypedef UniquePtr<char[], SecurityContext_Delete> Unique_SecurityContext; 591941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 601941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackbornclass MyShellCallback : public BnShellCallback 611941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn{ 621941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackbornpublic: 63e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn bool mActive = true; 64e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn 651941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn virtual int openOutputFile(const String16& path, const String16& seLinuxContext) { 661941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn String8 path8(path); 671941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn char cwd[256]; 681941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn getcwd(cwd, 256); 691941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn String8 fullPath(cwd); 701941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn fullPath.appendPath(path8); 71e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn if (!mActive) { 72e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn aerr << "Open attempt after active for: " << fullPath << endl; 73e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn return -EPERM; 74e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn } 751941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn int fd = open(fullPath.string(), O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU|S_IRWXG); 761941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn if (fd < 0) { 771941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn return fd; 781941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 791941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn if (is_selinux_enabled() && seLinuxContext.size() > 0) { 801941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn String8 seLinuxContext8(seLinuxContext); 811941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn security_context_t tmp = NULL; 821941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn int ret = getfilecon(fullPath.string(), &tmp); 831941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn Unique_SecurityContext context(tmp); 841941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn int accessGranted = selinux_check_access(seLinuxContext8.string(), context.get(), 851941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn "file", "write", NULL); 861941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn if (accessGranted != 0) { 871941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn close(fd); 881941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn aerr << "System server has no access to file context " << context.get() 891941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn << " (from path " << fullPath.string() << ", context " 901941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn << seLinuxContext8.string() << ")" << endl; 911941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn return -EPERM; 921941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 931941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 941941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn return fd; 951941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn } 961941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn}; 971941a404d642b3dfaac365ba494f1e9912876f00Dianne Hackborn 9823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornclass MyResultReceiver : public BnResultReceiver 9923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn{ 10023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornpublic: 1013d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn Mutex mMutex; 1023d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn Condition mCondition; 1033d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn bool mHaveResult = false; 1043d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn int32_t mResult = 0; 1053d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 1063d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn virtual void send(int32_t resultCode) { 1073d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn AutoMutex _l(mMutex); 1083d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mResult = resultCode; 1093d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mHaveResult = true; 1103d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mCondition.signal(); 1113d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 1123d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 1133d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn int32_t waitForResult() { 1143d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn AutoMutex _l(mMutex); 1153d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn while (!mHaveResult) { 1163d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn mCondition.wait(mMutex); 1173d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 1183d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn return mResult; 11923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 12023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn}; 12123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 12223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackbornint main(int argc, char* const argv[]) 12323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn{ 12423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn signal(SIGPIPE, SIG_IGN); 12523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<ProcessState> proc = ProcessState::self(); 126c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // setThreadPoolMaxThreadCount(0) actually tells the kernel it's 127c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // not allowed to spawn any additional threads, but we still spawn 128c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // a binder thread from userspace when we call startThreadPool(). 129c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // This is safe because we only have 2 callbacks, neither of which 130c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // block. 131c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen // See b/36066697 for rationale 132c21bc9afe403f52c189d2d6b79dedaf9dce6217bMartijn Coenen proc->setThreadPoolMaxThreadCount(0); 13323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn proc->startThreadPool(); 13423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 13523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<IServiceManager> sm = defaultServiceManager(); 13623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn fflush(stdout); 13723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (sm == NULL) { 1383d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGW("Unable to get default service manager!"); 13923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn aerr << "cmd: Unable to get default service manager!" << endl; 14023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 20; 14123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 14223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 14323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (argc == 1) { 1443d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn aerr << "cmd: No service specified; use -l to list all services" << endl; 14523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 20; 14623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 14723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 14823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) { 14923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn Vector<String16> services = sm->listServices(); 15023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn services.sort(sort_func); 15123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn aout << "Currently running services:" << endl; 15223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 15323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn for (size_t i=0; i<services.size(); i++) { 15423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<IBinder> service = sm->checkService(services[i]); 15523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (service != NULL) { 15623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn aout << " " << services[i] << endl; 15723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 15823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 15923eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 0; 16023eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 16123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 16223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn Vector<String16> args; 16323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn for (int i=2; i<argc; i++) { 16423eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn args.add(String16(argv[i])); 16523eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 16623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn String16 cmd = String16(argv[1]); 16723eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn sp<IBinder> service = sm->checkService(cmd); 16823eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn if (service == NULL) { 1693d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGW("Can't find service %s", argv[1]); 1703d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn aerr << "cmd: Can't find service: " << argv[1] << endl; 17123eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn return 20; 17223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn } 17323eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn 174e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn sp<MyShellCallback> cb = new MyShellCallback(); 1753d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn sp<MyResultReceiver> result = new MyResultReceiver(); 1763d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn 1773d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#if DEBUG 1783d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGD("cmd: Invoking %s in=%d, out=%d, err=%d", argv[1], STDIN_FILENO, STDOUT_FILENO, 1793d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn STDERR_FILENO); 1803d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#endif 181e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn 18223eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn // TODO: block until a result is returned to MyResultReceiver. 1833d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn status_t err = IBinder::shellCommand(service, STDIN_FILENO, STDOUT_FILENO, STDERR_FILENO, args, 1843d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn cb, result); 1853d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn if (err < 0) { 1863d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn const char* errstr; 1873d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn switch (err) { 1883d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case BAD_TYPE: errstr = "Bad type"; break; 1893d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case FAILED_TRANSACTION: errstr = "Failed transaction"; break; 1903d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case FDS_NOT_ALLOWED: errstr = "File descriptors not allowed"; break; 1913d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn case UNEXPECTED_NULL: errstr = "Unexpected null"; break; 1923d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn default: errstr = strerror(-err); break; 1933d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 1943d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGW("Failure calling service %s: %s (%d)", argv[1], errstr, -err); 1953d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn aout << "cmd: Failure calling service " << argv[1] << ": " << errstr << " (" 1963d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn << (-err) << ")" << endl; 1973d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn return err; 1983d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn } 199e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn 200e5ed19999d724b6f5131803ff56b3536349b58deDianne Hackborn cb->mActive = false; 2013d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn status_t res = result->waitForResult(); 2023d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#if DEBUG 2033d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn ALOGD("result=%d", (int)res); 2043d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn#endif 2053d9eb950b14ee6527a5a85d669bd03ce2bdcff32Dianne Hackborn return res; 20623eb1e20cf59e1238b65cc108f31dfbfd85b2337Dianne Hackborn} 207