installd.cpp revision 73dae11162aa61396c06cbdb05b954764e944e02
194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* 294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood** Copyright 2008, The Android Open Source Project 394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood** 419803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** Licensed under the Apache License, Version 2.0 (the "License"); 519803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** you may not use this file except in compliance with the License. 619803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** You may obtain a copy of the License at 794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood** 819803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** http://www.apache.org/licenses/LICENSE-2.0 994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood** 1019803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** Unless required by applicable law or agreed to in writing, software 1119803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** distributed under the License is distributed on an "AS IS" BASIS, 1219803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1319803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey** See the License for the specific language governing permissions and 1494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood** limitations under the License. 1594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood*/ 1694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 1702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <fcntl.h> 18bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley#include <selinux/android.h> 19bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley#include <selinux/avc.h> 2002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <sys/capability.h> 21c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey#include <sys/fsuid.h> 2202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <sys/prctl.h> 2302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <sys/socket.h> 2402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <sys/stat.h> 2502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 2602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <android-base/logging.h> 2702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <cutils/fs.h> 2802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <cutils/log.h> // TODO: Move everything to base::logging. 2902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <cutils/properties.h> 3002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <cutils/sockets.h> 3102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <private/android_filesystem_config.h> 3202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 3302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <commands.h> 3402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <globals.h> 3502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <installd_constants.h> 3602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <installd_deps.h> // Need to fill in requirements of commands. 3702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#include <utils.h> 3802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 3902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#ifndef LOG_TAG 4002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#define LOG_TAG "installd" 4102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#endif 4202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe#define SOCKET_PATH "installd" 4394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define BUFFER_MAX 1024 /* input buffer for commands */ 4588ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov#define TOKEN_MAX 16 /* max number of arguments in buffer */ 4694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood#define REPLY_MAX 256 /* largest reply allowed */ 4794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampenamespace android { 4902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampenamespace installd { 5002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 5102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe// Check that installd-deps sizes match cutils sizes. 5202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic_assert(kPropertyKeyMax == PROPERTY_KEY_MAX, "Size mismatch."); 5302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic_assert(kPropertyValueMax == PROPERTY_VALUE_MAX, "Size mismatch."); 5402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 5502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe//////////////////////// 5602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe// Plug-in functions. // 5702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe//////////////////////// 5802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 5902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampeint get_property(const char *key, char *value, const char *default_value) { 6002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return property_get(key, value, default_value); 6102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 6202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 6302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe// Compute the output path of 6402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool calculate_oat_file_path(char path[PKG_PATH_MAX], 6502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *oat_dir, 6602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *apk_path, 6702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *instruction_set) { 6802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char *file_name_start; 6902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char *file_name_end; 7002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 7102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe file_name_start = strrchr(apk_path, '/'); 7202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (file_name_start == NULL) { 7302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it\n", apk_path); 7402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 7502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 7602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe file_name_end = strrchr(apk_path, '.'); 7702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (file_name_end < file_name_start) { 7802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no extension\n", apk_path); 7902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 8002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 8102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 8202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe // Calculate file_name 8302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe int file_name_len = file_name_end - file_name_start - 1; 8402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char file_name[file_name_len + 1]; 8502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe memcpy(file_name, file_name_start + 1, file_name_len); 8602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe file_name[file_name_len] = '\0'; 8702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 8802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe // <apk_parent_dir>/oat/<isa>/<file_name>.odex 8902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe snprintf(path, PKG_PATH_MAX, "%s/%s/%s.odex", oat_dir, instruction_set, file_name); 9002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return true; 9102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 9202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 9302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe/* 9402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * Computes the odex file for the given apk_path and instruction_set. 9502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex 9602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * 9702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * Returns false if it failed to determine the odex file path. 9802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe */ 9902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool calculate_odex_file_path(char path[PKG_PATH_MAX], 10002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *apk_path, 10102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *instruction_set) { 10202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (strlen(apk_path) + strlen("oat/") + strlen(instruction_set) 10302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe + strlen("/") + strlen("odex") + 1 > PKG_PATH_MAX) { 10402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' may be too long to form odex file path.\n", apk_path); 10502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 10602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 10702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 10802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcpy(path, apk_path); 10902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char *end = strrchr(path, '/'); 11002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (end == NULL) { 11102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 11202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 11302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 11402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *apk_end = apk_path + (end - path); // strrchr(apk_path, '/'); 11502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 11602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcpy(end + 1, "oat/"); // path = /system/framework/oat/\0 11702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcat(path, instruction_set); // path = /system/framework/oat/<isa>\0 11802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcat(path, apk_end); // path = /system/framework/oat/<isa>/whatever.jar\0 11902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe end = strrchr(path, '.'); 12002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (end == NULL) { 12102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no extension.\n", apk_path); 12202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 12302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 12402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcpy(end + 1, "odex"); 12502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return true; 12602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 12702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 12802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool create_cache_path(char path[PKG_PATH_MAX], 12902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *src, 13002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *instruction_set) { 13102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe size_t srclen = strlen(src); 13202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 13302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe /* demand that we are an absolute path */ 13402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 13502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 13602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 13702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 13802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 13902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 14002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 14102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 14202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe size_t dstlen = 14302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe android_data_dir.len + 14402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(DALVIK_CACHE) + 14502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 1 + 14602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(instruction_set) + 14702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe srclen + 14802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(DALVIK_CACHE_POSTFIX) + 2; 14902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 15002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (dstlen > PKG_PATH_MAX) { 15102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 15202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 15302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 15402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe sprintf(path,"%s%s/%s/%s%s", 15502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe android_data_dir.path, 15602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe DALVIK_CACHE, 15702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe instruction_set, 15802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe src + 1, /* skip the leading / */ 15902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe DALVIK_CACHE_POSTFIX); 16002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 16102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char* tmp = 16202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe path + 16302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe android_data_dir.len + 16402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(DALVIK_CACHE) + 16502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 1 + 16602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(instruction_set) + 1; 16702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 16802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe for(; *tmp; tmp++) { 16902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (*tmp == '/') { 17002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe *tmp = '@'; 17102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 17202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 17302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 17402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return true; 17502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 17602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 17702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 1786fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkeystatic char* parse_null(char* arg) { 1796fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey if (strcmp(arg, "!") == 0) { 1806fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return nullptr; 1816fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey } else { 1826fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return arg; 1836fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey } 1846fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey} 1856fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey 18602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_ping(char **arg ATTRIBUTE_UNUSED, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 18794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 18894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 191c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_create_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 192c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags, 193eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis appid_t appid, const char* seinfo, int target_sdk_version */ 194eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis return create_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), 195eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis atoi(arg[4]), arg[5], atoi(arg[6])); 196c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 197c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 198c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_restorecon_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 199c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char* uuid, const char* pkgName, userid_t userid, int flags, 200c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey appid_t appid, const char* seinfo */ 201c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return restorecon_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]); 202c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 203c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 204c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_clear_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 205c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags */ 206c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return clear_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); 207c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 208c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 209c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_destroy_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 210c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags */ 211c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return destroy_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); 21294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 21473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int do_ota_dexopt(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 21573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Time to fork and run otapreopt. 21673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t pid = fork(); 21773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == 0) { 21873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* argv[1 + 9 + 1]; 21973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe argv[0] = "/system/bin/otapreopt"; 22073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (size_t i = 1; i <= 9; ++i) { 22173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe argv[i] = arg[i - 1]; 22273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 22373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe argv[10] = nullptr; 22473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 22573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe execv(argv[0], (char * const *)argv); 22673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("execv(OTAPREOPT) failed: %s\n", strerror(errno)); 22773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(99); 22873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 22973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int res = wait_child(pid); 23073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (res == 0) { 23173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGV("DexInv: --- END OTAPREOPT (success) ---\n"); 23273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 23373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("DexInv: --- END OTAPREOPT --- status=0x%04x, process failed\n", res); 23473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 23573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return res; 23673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 23773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 23873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 23973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int do_dexopt(char **arg, char reply[REPLY_MAX]) 24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 24173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int dexopt_flags = atoi(arg[6]); 24273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if ((dexopt_flags & DEXOPT_OTA) != 0) { 24373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return do_ota_dexopt(arg, reply); 24473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 24560a794dc845b942907ca035ddc554eb8e0c7ebb6Calin Juravle /* apk_path, uid, pkgname, instruction_set, dexopt_needed, oat_dir, dexopt_flags, volume_uuid, 24660a794dc845b942907ca035ddc554eb8e0c7ebb6Calin Juravle use_profiles */ 24776e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy return dexopt(arg[0], atoi(arg[1]), arg[2], arg[3], atoi(arg[4]), 24873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe arg[5], dexopt_flags, parse_null(arg[7]), (atoi(arg[8]) == 0 ? false : true)); 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 25102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 252091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath{ 253091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath return mark_boot_complete(arg[0] /* instruction set */); 254091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath} 255091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath 25602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2581b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath return rm_dex(arg[0], arg[1]); /* pkgname, instruction_set */ 25994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 26094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 26102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_free_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) /* TODO int:free_size */ 26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2636fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return free_cache(parse_null(arg[0]), (int64_t)atoll(arg[1])); /* uuid, free_size */ 26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 266c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_get_app_size(char **arg, char reply[REPLY_MAX]) { 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t codesize = 0; 26894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t datasize = 0; 26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t cachesize = 0; 27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t asecsize = 0; 27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = 0; 27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 273c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags, 274c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, 275c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey const char *asecpath, const char *instruction_set */ 276c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey res = get_app_size(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4], arg[5], 277c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey arg[6], arg[7], arg[8], &codesize, &datasize, &cachesize, &asecsize); 27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* 28094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * Each int64_t can take up 22 characters printed out. Make sure it 28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * doesn't go over REPLY_MAX in the future. 28294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, 28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood codesize, datasize, cachesize, asecsize); 28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 288c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_move_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 289c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char* from_uuid, const char *to_uuid, const char *package_name, 290eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis const char *data_app_name, appid_t appid, const char* seinfo, 291eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis int target_sdk_version */ 292eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], 293eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis atoi(arg[4]), arg[5], atoi(arg[6])); 29494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 29594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 29602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_mk_user_config(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 297095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee{ 2987c8bec01790087748ec7afa69a31789828b751f9Robin Lee return make_user_config(atoi(arg[0])); /* userid */ 299095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee} 300095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 30102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_user(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 30294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3036fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return delete_user(parse_null(arg[0]), atoi(arg[1])); /* uuid, userid */ 30494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 30594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_linklib(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 30794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3086fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return linklib(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3])); 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_idmap(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 31263568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad{ 31363568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad return idmap(arg[0], arg[1], atoi(arg[2])); 31463568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad} 31563568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad 31602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_create_oat_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 31788ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 31888ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir, instruction_set */ 31988ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return create_oat_dir(arg[0], arg[1]); 32088ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov} 32188ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov 32202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_package_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 32388ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 32488ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir */ 32588ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return rm_package_dir(arg[0]); 32643c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light} 32743c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light 32802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_link_file(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 329d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath{ 330d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath /* relative_path, from_base, to_base */ 331d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath return link_file(arg[0], arg[1], arg[2]); 332d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath} 333d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath 33494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo { 33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char *name; 33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned numargs; 33794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int (*func)(char **arg, char reply[REPLY_MAX]); 33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 34094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo cmds[] = { 34194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "ping", 0, do_ping }, 342c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 343eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis { "create_app_data", 7, do_create_app_data }, 344c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "restorecon_app_data", 6, do_restorecon_app_data }, 345c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "clear_app_data", 4, do_clear_app_data }, 346c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "destroy_app_data", 4, do_destroy_app_data }, 347eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis { "move_complete_app", 7, do_move_complete_app }, 348c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "get_app_size", 9, do_get_app_size }, 349c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 35060a794dc845b942907ca035ddc554eb8e0c7ebb6Calin Juravle { "dexopt", 9, do_dexopt }, 351091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "markbootcomplete", 1, do_mark_boot_complete }, 3521b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath { "rmdex", 2, do_rm_dex }, 3536fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "freecache", 2, do_free_cache }, 3546fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "linklib", 4, do_linklib }, 3557c8bec01790087748ec7afa69a31789828b751f9Robin Lee { "mkuserconfig", 1, do_mk_user_config }, 3566fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "rmuser", 2, do_rm_user }, 35763568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad { "idmap", 3, do_idmap }, 35888ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov { "createoatdir", 2, do_create_oat_dir }, 359d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath { "rmpackagedir", 1, do_rm_package_dir }, 360c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "linkfile", 3, do_link_file }, 36194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int readx(int s, void *_buf, int count) 36494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 36519803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey char *buf = (char *) _buf; 36694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 36794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 36894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 36994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = read(s, buf + n, count - n); 37094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 37294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("read error: %s\n", strerror(errno)); 37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r == 0) { 37694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("eof\n"); 37794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; /* EOF */ 37894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 38294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 38394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int writex(int s, const void *_buf, int count) 38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 38619803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey const char *buf = (const char *) _buf; 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 39094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = write(s, buf + n, count - n); 39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("write error: %s\n", strerror(errno)); 39494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 39794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 39994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Tokenize the command buffer, locate a matching command, 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * ensure that the required number of arguments are provided, 40494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * call the function(), return the result. 40594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int execute(int s, char cmd[BUFFER_MAX]) 40794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 40894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char reply[REPLY_MAX]; 40994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *arg[TOKEN_MAX+1]; 41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned i; 41194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned n = 0; 41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int ret = -1; 41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4151705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("execute('%s')\n", cmd); 41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* default reply is "" */ 41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply[0] = 0; 41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* n is number of args (not counting arg[0]) */ 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[0] = cmd; 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*cmd) { 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (isspace(*cmd)) { 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *cmd++ = 0; 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n++; 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[n] = cmd; 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n == TOKEN_MAX) { 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("too many arguments\n"); 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 43262bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov if (*cmd) { 43362bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov cmd++; 43462bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov } 43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 43694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { 43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!strcmp(cmds[i].name,arg[0])) { 43994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n != cmds[i].numargs) { 44094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("%s requires %d arguments (%d given)\n", 44194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmds[i].name, cmds[i].numargs, n); 44294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 44394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = cmds[i].func(arg + 1, reply); 44494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 44694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 44794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 44894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("unsupported command '%s'\n", arg[0]); 44994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddone: 45194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (reply[0]) { 45294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); 45394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 45494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d", ret); 45594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 45694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n > BUFFER_MAX) n = BUFFER_MAX; 45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood count = n; 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4591705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("reply: '%s'\n", cmd); 46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, &count, sizeof(count))) return -1; 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, cmd, count)) return -1; 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool initialize_globals() { 46602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* data_path = getenv("ANDROID_DATA"); 46702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (data_path == nullptr) { 46802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_DATA"); 46902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* root_path = getenv("ANDROID_ROOT"); 47202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (root_path == nullptr) { 47302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_ROOT"); 47402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return init_globals_from_data_and_root(data_path, root_path); 47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int initialize_directories() { 48194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = -1; 48294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Read current filesystem layout version to handle upgrade paths 48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char version_path[PATH_MAX]; 48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path); 48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int oldVersion; 48894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_read_atomic_int(version_path, &oldVersion) == -1) { 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood oldVersion = 0; 49094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int version = oldVersion; 49294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 493e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey if (version < 2) { 494e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey SLOGD("Assuming that device has multi-user storage layout; upgrade no longer supported"); 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood version = 2; 49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49807053fcb61436221fac2281394e98ec9d0feab3dRobin Lee if (ensure_config_user_dirs(0) == -1) { 49907053fcb61436221fac2281394e98ec9d0feab3dRobin Lee ALOGE("Failed to setup misc for user 0"); 50007053fcb61436221fac2281394e98ec9d0feab3dRobin Lee goto fail; 50107053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 50207053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 503095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (version == 2) { 504095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee ALOGD("Upgrading to /data/misc/user directories"); 505095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 50660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_dir[PATH_MAX]; 50760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.path); 50860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 50960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_added_dir[PATH_MAX]; 51060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); 51160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 51260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_removed_dir[PATH_MAX]; 51360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); 51460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 515095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee DIR *dir; 516095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee struct dirent *dirent; 517e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey dir = opendir("/data/user"); 518095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (dir != NULL) { 519095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee while ((dirent = readdir(dir))) { 52060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee const char *name = dirent->d_name; 521095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 52260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // skip "." and ".." 52360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[0] == '.') { 52460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[1] == 0) continue; 52560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if ((name[1] == '.') && (name[2] == 0)) continue; 52660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 527095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 52860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uint32_t user_id = atoi(name); 52960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 53060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // /data/misc/user/<user_id> 53160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (ensure_config_user_dirs(user_id) == -1) { 53260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee goto fail; 53360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 53460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 53560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_added_dir[PATH_MAX]; 53660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name); 53760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 53860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_removed_dir[PATH_MAX]; 53960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name); 54060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 54160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM); 54260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee gid_t gid = uid; 54360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 54460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) { 54560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 54660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 54760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 54860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 54960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) { 55060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 551095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 552095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 553095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 554095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee closedir(dir); 55507053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 55660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 55760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_added_dir, 1, 0); 55807053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 55960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 56060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_removed_dir, 1, 0); 56107053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 56207053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 563095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 56407053fcb61436221fac2281394e98ec9d0feab3dRobin Lee version = 3; 565095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 566095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 56794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Persist layout version if changed 56894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (version != oldVersion) { 56994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_write_atomic_int(version_path, version) == -1) { 57094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to save version to %s: %s", version_path, strerror(errno)); 57194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 57294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 57394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 57494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Success! 57694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = 0; 57794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail: 57994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 58094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 58194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5827abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalleystatic int log_callback(int type, const char *fmt, ...) { 5837abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_list ap; 5847abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley int priority; 5857abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 5867abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley switch (type) { 5877abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_WARNING: 5887abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_WARN; 5897abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 5907abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_INFO: 5917abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_INFO; 5927abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 5937abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley default: 5947abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_ERROR; 5957abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 5967abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley } 5977abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_start(ap, fmt); 5987abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley LOG_PRI_VA(priority, "SELinux", fmt, ap); 5997abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_end(ap); 6007abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley return 0; 6017abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley} 6027abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 60302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { 60494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char buf[BUFFER_MAX]; 60594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct sockaddr addr; 60694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood socklen_t alen; 60799d9fb15b4a1eb534261ae81b2cf25aec4447bd0Chih-Hung Hsieh int lsocket, s; 608bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley int selinux_enabled = (is_selinux_enabled() > 0); 60994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 610e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey setenv("ANDROID_LOG_TAGS", "*:v", 1); 611e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey android::base::InitLogging(argv); 612e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 61394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("installd firing up\n"); 61494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6157abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley union selinux_callback cb; 6167abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley cb.func_log = log_callback; 6177abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley selinux_set_callback(SELINUX_CB_LOG, cb); 6187abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 61902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (!initialize_globals()) { 62094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not initialize globals; exiting.\n"); 62194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 62294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 62394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 62494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (initialize_directories() < 0) { 62594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not create directories; exiting.\n"); 62694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 62794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 62894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 629bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_open(true) < 0) { 630bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley ALOGE("Could not open selinux status; exiting.\n"); 631bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley exit(1); 632bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 633bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley 63494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood lsocket = android_get_control_socket(SOCKET_PATH); 63594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (lsocket < 0) { 63694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); 63794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 63894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 63994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (listen(lsocket, 5)) { 64094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Listen on socket failed: %s\n", strerror(errno)); 64194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 64294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 64394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(lsocket, F_SETFD, FD_CLOEXEC); 64494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 64594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 64694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood alen = sizeof(addr); 64794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = accept(lsocket, &addr, &alen); 64894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (s < 0) { 64994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Accept failed: %s\n", strerror(errno)); 65094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 65194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 65294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(s, F_SETFD, FD_CLOEXEC); 65394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 65494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("new connection\n"); 65594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 65694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 65794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, &count, sizeof(count))) { 65894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read size\n"); 65994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 66094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 66194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count < 1) || (count >= BUFFER_MAX)) { 66294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("invalid size %d\n", count); 66394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 66494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 66594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, buf, count)) { 66694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read command\n"); 66794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 66894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 66994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood buf[count] = 0; 670bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_updated() > 0) { 671bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley selinux_android_seapp_context_reload(); 672bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 67394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (execute(s, buf)) break; 67494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 67594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("closing connection\n"); 67694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(s); 67794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 67894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 67994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 68094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 68102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 68202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace installd 68302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace android 68402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 68502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampeint main(const int argc, char *argv[]) { 68602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return android::installd::installd_main(argc, argv); 68702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 688