1b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin/*
2b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * Copyright (C) 2017 The Android Open Source Project
3b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin *
4b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * Licensed under the Apache License, Version 2.0 (the "License");
5b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * you may not use this file except in compliance with the License.
6b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * You may obtain a copy of the License at
7b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin *
8b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin *      http://www.apache.org/licenses/LICENSE-2.0
9b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin *
10b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * Unless required by applicable law or agreed to in writing, software
11b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * distributed under the License is distributed on an "AS IS" BASIS,
12b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * See the License for the specific language governing permissions and
14b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin * limitations under the License.
15b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin */
161a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin#define DEBUG false
171a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin#include "Log.h"
181a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin
19b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "incidentd_util.h"
20b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
211a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin#include <sys/prctl.h>
22c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin#include <wait.h>
231a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin
24b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin#include "section_list.h"
25b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
266cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace android {
276cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace os {
286cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinnamespace incidentd {
296cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
306cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jinusing namespace android::base;
316cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
32b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinconst Privacy* get_privacy_of_section(int id) {
33b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    int l = 0;
34b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    int r = PRIVACY_POLICY_COUNT - 1;
35b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    while (l <= r) {
36b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        int mid = (l + r) >> 1;
37b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        const Privacy* p = PRIVACY_POLICY_LIST[mid];
38b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
39b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        if (p->field_id < (uint32_t)id) {
40b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            l = mid + 1;
41b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        } else if (p->field_id > (uint32_t)id) {
42b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            r = mid - 1;
43b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        } else {
44b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin            return p;
45b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin        }
46b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    }
47b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    return NULL;
48b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin}
49b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
50b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin// ================================================================================
51b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinFpipe::Fpipe() : mRead(), mWrite() {}
52b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
53b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi JinFpipe::~Fpipe() { close(); }
54b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
55b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinbool Fpipe::close() {
56b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    mRead.reset();
57b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    mWrite.reset();
58b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin    return true;
59b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin}
60b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
61b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jinbool Fpipe::init() { return Pipe(&mRead, &mWrite); }
62b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
636355d2f3ab5febbd25331a72671eea47ef5f43acYi Jinunique_fd& Fpipe::readFd() { return mRead; }
64b592e3bc3169e39bd6b0bfce9f788631d5d22acdYi Jin
656355d2f3ab5febbd25331a72671eea47ef5f43acYi Jinunique_fd& Fpipe::writeFd() { return mWrite; }
661a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin
67c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jinpid_t fork_execute_cmd(char* const argv[], Fpipe* input, Fpipe* output) {
681a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    // fork used in multithreaded environment, avoid adding unnecessary code in child process
691a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    pid_t pid = fork();
701a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    if (pid == 0) {
71c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        VLOG("[In child]cmd %s", argv[0]);
72c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        if (input != NULL && (TEMP_FAILURE_RETRY(dup2(input->readFd().get(), STDIN_FILENO)) < 0 ||
73c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin                              !input->close())) {
74c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin            ALOGW("Failed to dup2 stdin.");
75c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin            _exit(EXIT_FAILURE);
76c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        }
77c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        if (TEMP_FAILURE_RETRY(dup2(output->writeFd().get(), STDOUT_FILENO)) < 0 ||
786355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin            !output->close()) {
79c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin            ALOGW("Failed to dup2 stdout.");
801a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin            _exit(EXIT_FAILURE);
811a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin        }
821a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin        /* make sure the child dies when incidentd dies */
831a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin        prctl(PR_SET_PDEATHSIG, SIGKILL);
84c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        execvp(argv[0], argv);
85c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        _exit(errno);  // always exits with failure if any
861a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    }
871a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    // close the fds used in child process.
88c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    if (input != NULL) input->readFd().reset();
896355d2f3ab5febbd25331a72671eea47ef5f43acYi Jin    output->writeFd().reset();
901a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    return pid;
911a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin}
92eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams
931a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin// ================================================================================
941a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jinconst char** varargs(const char* first, va_list rest) {
951a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    va_list copied_rest;
961a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    int numOfArgs = 1;  // first is already count.
971a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin
981a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    va_copy(copied_rest, rest);
991a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    while (va_arg(copied_rest, const char*) != NULL) {
1001a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin        numOfArgs++;
1011a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    }
1021a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    va_end(copied_rest);
1031a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin
1041a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    // allocate extra 1 for NULL terminator
1051a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    const char** ret = (const char**)malloc(sizeof(const char*) * (numOfArgs + 1));
1061a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    ret[0] = first;
10706ebd1af8ec49d647bc59ac3d3d5a0930095ba45Yi Jin    for (int i = 1; i < numOfArgs; i++) {
1081a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin        const char* arg = va_arg(rest, const char*);
10906ebd1af8ec49d647bc59ac3d3d5a0930095ba45Yi Jin        ret[i] = arg;
1101a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    }
11106ebd1af8ec49d647bc59ac3d3d5a0930095ba45Yi Jin    ret[numOfArgs] = NULL;
1121a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin    return ret;
1131a11fa10977ee1e2645d400844ff4d472b8f5f02Yi Jin}
114eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams
115eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams// ================================================================================
116eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adamsconst uint64_t NANOS_PER_SEC = 1000000000;
117eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adamsuint64_t Nanotime() {
118eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    timespec ts;
119eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    clock_gettime(CLOCK_MONOTONIC, &ts);
120eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams    return static_cast<uint64_t>(ts.tv_sec * NANOS_PER_SEC + ts.tv_nsec);
121eadd123d68850cb27aa6d030ade6190e30991b19Kweku Adams}
122c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin
123c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin// ================================================================================
124c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jinconst int WAIT_MAX = 5;
125c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jinconst struct timespec WAIT_INTERVAL_NS = {0, 200 * 1000 * 1000};
126c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin
127c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jinstatic status_t statusCode(int status) {
128c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    if (WIFSIGNALED(status)) {
129c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        VLOG("return by signal: %s", strerror(WTERMSIG(status)));
130c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        return -WTERMSIG(status);
131c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    } else if (WIFEXITED(status) && WEXITSTATUS(status) > 0) {
132c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        VLOG("return by exit: %s", strerror(WEXITSTATUS(status)));
133c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        return -WEXITSTATUS(status);
134c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    }
135c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    return NO_ERROR;
136c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin}
137c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin
138c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jinstatus_t kill_child(pid_t pid) {
139c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    int status;
140c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    VLOG("try to kill child process %d", pid);
141c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    kill(pid, SIGKILL);
142c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    if (waitpid(pid, &status, 0) == -1) return -1;
143c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    return statusCode(status);
144c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin}
145c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin
146c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jinstatus_t wait_child(pid_t pid) {
147c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    int status;
148c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    bool died = false;
149c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    // wait for child to report status up to 1 seconds
150c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    for (int loop = 0; !died && loop < WAIT_MAX; loop++) {
151c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        if (waitpid(pid, &status, WNOHANG) == pid) died = true;
152c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        // sleep for 0.2 second
153c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin        nanosleep(&WAIT_INTERVAL_NS, NULL);
154c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    }
155c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    if (!died) return kill_child(pid);
156c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin    return statusCode(status);
157c36e91dd127751b54ef0886175b56b4a2e6af28cYi Jin}
1586cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin
1596cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace incidentd
1606cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace os
1616cacbcbf436be744a34f7ea0d4f838ff97757446Yi Jin}  // namespace android