InstalldNativeService.cpp revision 9087400f3c82b97aa17a74329c7e65c0a5ff4062
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#define LOG_TAG "installd"
18
19#include <vector>
20#include <fstream>
21
22#include <android-base/stringprintf.h>
23#include <binder/IPCThreadState.h>
24#include <binder/IServiceManager.h>
25#include <cutils/log.h>
26#include <cutils/properties.h>
27#include <private/android_filesystem_config.h>
28#include <utils/Errors.h>
29#include <utils/String16.h>
30
31#include "InstalldNativeService.h"
32
33#include "commands.h"
34
35using android::base::StringPrintf;
36
37namespace android {
38namespace installd {
39
40namespace {
41
42constexpr const char* kDump = "android.permission.DUMP";
43
44binder::Status checkPermission(const char* permission) {
45    pid_t pid;
46    uid_t uid;
47
48    if (checkCallingPermission(String16(permission), reinterpret_cast<int32_t*>(&pid),
49            reinterpret_cast<int32_t*>(&uid))) {
50        return binder::Status::ok();
51    } else {
52        auto err = StringPrintf("UID %d / PID %d lacks permission %s", uid, pid, permission);
53        return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(err.c_str()));
54    }
55}
56
57binder::Status checkUid(uid_t expectedUid) {
58    uid_t uid = IPCThreadState::self()->getCallingUid();
59    if (uid == expectedUid) {
60        return binder::Status::ok();
61    } else {
62        auto err = StringPrintf("UID %d is not expected UID %d", uid, expectedUid);
63        return binder::Status::fromExceptionCode(binder::Status::EX_SECURITY, String8(err.c_str()));
64    }
65}
66
67#define ENFORCE_UID(uid) {                                  \
68    binder::Status status = checkUid((uid));                \
69    if (!status.isOk()) {                                   \
70        return status;                                      \
71    }                                                       \
72}
73
74}  // namespace
75
76status_t InstalldNativeService::start() {
77    IPCThreadState::self()->disableBackgroundScheduling(true);
78    status_t ret = BinderService<InstalldNativeService>::publish();
79    if (ret != android::OK) {
80        return ret;
81    }
82    sp<ProcessState> ps(ProcessState::self());
83    ps->startThreadPool();
84    ps->giveThreadPoolName();
85    return android::OK;
86}
87
88status_t InstalldNativeService::dump(int fd, const Vector<String16> & /* args */) {
89    const binder::Status dump_permission = checkPermission(kDump);
90    if (!dump_permission.isOk()) {
91        const String8 msg(dump_permission.toString8());
92        write(fd, msg.string(), msg.size());
93        return PERMISSION_DENIED;
94    }
95
96    std::string msg = "installd is happy\n";
97    write(fd, msg.c_str(), strlen(msg.c_str()));
98    return NO_ERROR;
99}
100
101static binder::Status translateStatus(int ret) {
102    if (ret != 0) {
103        auto err = StringPrintf("Failed with error %d", ret);
104        return binder::Status::fromServiceSpecificError(ret, String8(err.c_str()));
105    } else {
106        return binder::Status::ok();
107    }
108}
109
110binder::Status InstalldNativeService::createAppData(const std::unique_ptr<std::string>& uuid,
111        const std::string& pkgname, int32_t userid, int32_t flags, int32_t appid,
112        const std::string& seinfo, int32_t targetSdkVersion) {
113    ENFORCE_UID(AID_SYSTEM);
114    const char* _uuid = uuid ? (*uuid).c_str() : nullptr;
115    return translateStatus(create_app_data(_uuid, pkgname.c_str(), userid, flags, appid,
116            seinfo.c_str(), targetSdkVersion));
117}
118
119}  // namespace installd
120}  // namespace android
121