installd.cpp revision 00087b70401bd09dfeaab9171d006e833e3cd844
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) { 13100087b70401bd09dfeaab9171d006e833e3cd844Greg Kaiser /* demand that we are an absolute path */ 13200087b70401bd09dfeaab9171d006e833e3cd844Greg Kaiser if ((src == nullptr) || (src[0] != '/') || strstr(src,"..")) { 13302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 13402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 13502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 13600087b70401bd09dfeaab9171d006e833e3cd844Greg Kaiser size_t srclen = strlen(src); 13700087b70401bd09dfeaab9171d006e833e3cd844Greg Kaiser 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 204cc6281cf8146cddb8ace7cbd58c67321639c1520Jeff Sharkeystatic int do_migrate_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 205cc6281cf8146cddb8ace7cbd58c67321639c1520Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags */ 206cc6281cf8146cddb8ace7cbd58c67321639c1520Jeff Sharkey return migrate_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); 207cc6281cf8146cddb8ace7cbd58c67321639c1520Jeff Sharkey} 208cc6281cf8146cddb8ace7cbd58c67321639c1520Jeff Sharkey 209c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_clear_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 clear_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); 212c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 213c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 214c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_destroy_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 215c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags */ 216c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return destroy_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); 21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 21973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int do_ota_dexopt(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 22073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe // Time to fork and run otapreopt. 22173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe pid_t pid = fork(); 22273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (pid == 0) { 22373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe const char* argv[1 + 9 + 1]; 22473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe argv[0] = "/system/bin/otapreopt"; 22573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe for (size_t i = 1; i <= 9; ++i) { 22673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe argv[i] = arg[i - 1]; 22773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 22873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe argv[10] = nullptr; 22973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 23073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe execv(argv[0], (char * const *)argv); 23173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("execv(OTAPREOPT) failed: %s\n", strerror(errno)); 23273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe exit(99); 23373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 23473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int res = wait_child(pid); 23573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if (res == 0) { 23673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGV("DexInv: --- END OTAPREOPT (success) ---\n"); 23773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 23873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe ALOGE("DexInv: --- END OTAPREOPT --- status=0x%04x, process failed\n", res); 23973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 24073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return res; 24173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 24273dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 24373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 24473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int do_dexopt(char **arg, char reply[REPLY_MAX]) 24594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 24673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int dexopt_flags = atoi(arg[6]); 24773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if ((dexopt_flags & DEXOPT_OTA) != 0) { 24873dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe return do_ota_dexopt(arg, reply); 24973dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 25060a794dc845b942907ca035ddc554eb8e0c7ebb6Calin Juravle /* apk_path, uid, pkgname, instruction_set, dexopt_needed, oat_dir, dexopt_flags, volume_uuid, 25160a794dc845b942907ca035ddc554eb8e0c7ebb6Calin Juravle use_profiles */ 25276e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy return dexopt(arg[0], atoi(arg[1]), arg[2], arg[3], atoi(arg[4]), 25373dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe arg[5], dexopt_flags, parse_null(arg[7]), (atoi(arg[8]) == 0 ? false : true)); 25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 25602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 257091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath{ 258091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath return mark_boot_complete(arg[0] /* instruction set */); 259091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath} 260091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath 26102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 26294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2631b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath return rm_dex(arg[0], arg[1]); /* pkgname, instruction_set */ 26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 26594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 26602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_free_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) /* TODO int:free_size */ 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2686fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return free_cache(parse_null(arg[0]), (int64_t)atoll(arg[1])); /* uuid, free_size */ 26994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 27094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 271c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_get_app_size(char **arg, char reply[REPLY_MAX]) { 27294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t codesize = 0; 27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t datasize = 0; 27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t cachesize = 0; 27594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t asecsize = 0; 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = 0; 27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 278c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags, 279c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, 280c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey const char *asecpath, const char *instruction_set */ 281c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey res = get_app_size(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4], arg[5], 282c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey arg[6], arg[7], arg[8], &codesize, &datasize, &cachesize, &asecsize); 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* 28594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * Each int64_t can take up 22 characters printed out. Make sure it 28694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * doesn't go over REPLY_MAX in the future. 28794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 28894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, 28994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood codesize, datasize, cachesize, asecsize); 29094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 29194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 29294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 293c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_move_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 294c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char* from_uuid, const char *to_uuid, const char *package_name, 295eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis const char *data_app_name, appid_t appid, const char* seinfo, 296eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis int target_sdk_version */ 297eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], 298eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis atoi(arg[4]), arg[5], atoi(arg[6])); 29994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 30094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 30102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_mk_user_config(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 302095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee{ 3037c8bec01790087748ec7afa69a31789828b751f9Robin Lee return make_user_config(atoi(arg[0])); /* userid */ 304095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee} 305095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 30602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_user(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 30794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3086fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return delete_user(parse_null(arg[0]), atoi(arg[1])); /* uuid, userid */ 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_linklib(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3136fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return linklib(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3])); 31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_idmap(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 31763568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad{ 31863568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad return idmap(arg[0], arg[1], atoi(arg[2])); 31963568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad} 32063568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad 32102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_create_oat_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 32288ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 32388ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir, instruction_set */ 32488ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return create_oat_dir(arg[0], arg[1]); 32588ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov} 32688ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov 32702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_package_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 32888ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 32988ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir */ 33088ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return rm_package_dir(arg[0]); 33143c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light} 33243c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light 333d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdilstatic int do_rm_profiles(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 334d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil{ 335d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil /* package_name */ 336d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil return rm_profiles(arg[0]); 337d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil} 338d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil 33902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_link_file(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 340d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath{ 341d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath /* relative_path, from_base, to_base */ 342d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath return link_file(arg[0], arg[1], arg[2]); 343d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath} 344d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath 345e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampestatic int do_move_ab(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 346e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe // apk_path, instruction_set, oat_dir 347e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe return move_ab(arg[0], arg[1], arg[2]); 348e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe} 349e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo { 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char *name; 35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned numargs; 35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int (*func)(char **arg, char reply[REPLY_MAX]); 35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo cmds[] = { 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "ping", 0, do_ping }, 358c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 359eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis { "create_app_data", 7, do_create_app_data }, 360c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "restorecon_app_data", 6, do_restorecon_app_data }, 361cc6281cf8146cddb8ace7cbd58c67321639c1520Jeff Sharkey { "migrate_app_data", 4, do_migrate_app_data }, 362c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "clear_app_data", 4, do_clear_app_data }, 363c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "destroy_app_data", 4, do_destroy_app_data }, 364eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis { "move_complete_app", 7, do_move_complete_app }, 365c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "get_app_size", 9, do_get_app_size }, 366c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 36760a794dc845b942907ca035ddc554eb8e0c7ebb6Calin Juravle { "dexopt", 9, do_dexopt }, 368091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "markbootcomplete", 1, do_mark_boot_complete }, 3691b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath { "rmdex", 2, do_rm_dex }, 3706fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "freecache", 2, do_free_cache }, 3716fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "linklib", 4, do_linklib }, 3727c8bec01790087748ec7afa69a31789828b751f9Robin Lee { "mkuserconfig", 1, do_mk_user_config }, 3736fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "rmuser", 2, do_rm_user }, 37463568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad { "idmap", 3, do_idmap }, 37588ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov { "createoatdir", 2, do_create_oat_dir }, 376d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath { "rmpackagedir", 1, do_rm_package_dir }, 377d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil { "rmprofiles", 1, do_rm_profiles }, 378c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "linkfile", 3, do_link_file }, 379e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe { "move_ab", 3, do_move_ab }, 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int readx(int s, void *_buf, int count) 38394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 38419803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey char *buf = (char *) _buf; 38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = read(s, buf + n, count - n); 38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 39094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("read error: %s\n", strerror(errno)); 39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r == 0) { 39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("eof\n"); 39694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; /* EOF */ 39794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 39994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int writex(int s, const void *_buf, int count) 40494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 40519803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey const char *buf = (const char *) _buf; 40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 40794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 40894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 40994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = write(s, buf + n, count - n); 41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 41194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("write error: %s\n", strerror(errno)); 41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 41594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Tokenize the command buffer, locate a matching command, 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * ensure that the required number of arguments are provided, 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * call the function(), return the result. 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int execute(int s, char cmd[BUFFER_MAX]) 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char reply[REPLY_MAX]; 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *arg[TOKEN_MAX+1]; 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned i; 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned n = 0; 43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 43294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int ret = -1; 43394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4341705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("execute('%s')\n", cmd); 43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 43694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* default reply is "" */ 43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply[0] = 0; 43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 43994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* n is number of args (not counting arg[0]) */ 44094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[0] = cmd; 44194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*cmd) { 44294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (isspace(*cmd)) { 44394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *cmd++ = 0; 44494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n++; 44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[n] = cmd; 44694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n == TOKEN_MAX) { 44794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("too many arguments\n"); 44894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 44994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 45094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 45162bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov if (*cmd) { 45262bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov cmd++; 45362bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov } 45494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 45594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { 45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!strcmp(cmds[i].name,arg[0])) { 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n != cmds[i].numargs) { 45994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("%s requires %d arguments (%d given)\n", 46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmds[i].name, cmds[i].numargs, n); 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = cmds[i].func(arg + 1, reply); 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("unsupported command '%s'\n", arg[0]); 46894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddone: 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (reply[0]) { 47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); 47294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 47394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d", ret); 47494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n > BUFFER_MAX) n = BUFFER_MAX; 47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood count = n; 47794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4781705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("reply: '%s'\n", cmd); 47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, &count, sizeof(count))) return -1; 48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, cmd, count)) return -1; 48194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 48294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 48402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool initialize_globals() { 48502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* data_path = getenv("ANDROID_DATA"); 48602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (data_path == nullptr) { 48702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_DATA"); 48802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* root_path = getenv("ANDROID_ROOT"); 49102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (root_path == nullptr) { 49202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_ROOT"); 49302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return init_globals_from_data_and_root(data_path, root_path); 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int initialize_directories() { 50094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = -1; 50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Read current filesystem layout version to handle upgrade paths 50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char version_path[PATH_MAX]; 50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path); 50594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int oldVersion; 50794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_read_atomic_int(version_path, &oldVersion) == -1) { 50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood oldVersion = 0; 50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int version = oldVersion; 51194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 512e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey if (version < 2) { 513e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey SLOGD("Assuming that device has multi-user storage layout; upgrade no longer supported"); 51494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood version = 2; 51594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51707053fcb61436221fac2281394e98ec9d0feab3dRobin Lee if (ensure_config_user_dirs(0) == -1) { 51807053fcb61436221fac2281394e98ec9d0feab3dRobin Lee ALOGE("Failed to setup misc for user 0"); 51907053fcb61436221fac2281394e98ec9d0feab3dRobin Lee goto fail; 52007053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 52107053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 522095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (version == 2) { 523095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee ALOGD("Upgrading to /data/misc/user directories"); 524095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 52560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_dir[PATH_MAX]; 52660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.path); 52760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 52860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_added_dir[PATH_MAX]; 52960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); 53060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 53160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_removed_dir[PATH_MAX]; 53260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); 53360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 534095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee DIR *dir; 535095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee struct dirent *dirent; 536e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey dir = opendir("/data/user"); 537095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (dir != NULL) { 538095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee while ((dirent = readdir(dir))) { 53960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee const char *name = dirent->d_name; 540095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 54160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // skip "." and ".." 54260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[0] == '.') { 54360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[1] == 0) continue; 54460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if ((name[1] == '.') && (name[2] == 0)) continue; 54560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 546095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 54760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uint32_t user_id = atoi(name); 54860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 54960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // /data/misc/user/<user_id> 55060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (ensure_config_user_dirs(user_id) == -1) { 55160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee goto fail; 55260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 55360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 55460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_added_dir[PATH_MAX]; 55560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name); 55660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 55760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_removed_dir[PATH_MAX]; 55860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name); 55960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 56060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM); 56160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee gid_t gid = uid; 56260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 56360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) { 56460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 56560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 56660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 56760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 56860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) { 56960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 570095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 571095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 572095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 573095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee closedir(dir); 57407053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 57560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 57660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_added_dir, 1, 0); 57707053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 57860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 57960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_removed_dir, 1, 0); 58007053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 58107053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 582095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 58307053fcb61436221fac2281394e98ec9d0feab3dRobin Lee version = 3; 584095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 585095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 58694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Persist layout version if changed 58794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (version != oldVersion) { 58894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_write_atomic_int(version_path, version) == -1) { 58994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to save version to %s: %s", version_path, strerror(errno)); 59094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 59194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 59294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 59394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Success! 59594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = 0; 59694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail: 59894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 59994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 60094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6017abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalleystatic int log_callback(int type, const char *fmt, ...) { 6027abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_list ap; 6037abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley int priority; 6047abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 6057abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley switch (type) { 6067abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_WARNING: 6077abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_WARN; 6087abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6097abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_INFO: 6107abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_INFO; 6117abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6127abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley default: 6137abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_ERROR; 6147abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6157abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley } 6167abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_start(ap, fmt); 6177abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley LOG_PRI_VA(priority, "SELinux", fmt, ap); 6187abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_end(ap); 6197abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley return 0; 6207abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley} 6217abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 62202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { 62394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char buf[BUFFER_MAX]; 62494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct sockaddr addr; 62594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood socklen_t alen; 62699d9fb15b4a1eb534261ae81b2cf25aec4447bd0Chih-Hung Hsieh int lsocket, s; 627bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley int selinux_enabled = (is_selinux_enabled() > 0); 62894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 629e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey setenv("ANDROID_LOG_TAGS", "*:v", 1); 630e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey android::base::InitLogging(argv); 631e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 63294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("installd firing up\n"); 63394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6347abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley union selinux_callback cb; 6357abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley cb.func_log = log_callback; 6367abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley selinux_set_callback(SELINUX_CB_LOG, cb); 6377abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 63802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (!initialize_globals()) { 63994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not initialize globals; exiting.\n"); 64094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 64194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 64294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 64394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (initialize_directories() < 0) { 64494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not create directories; exiting.\n"); 64594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 64694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 64794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 648bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_open(true) < 0) { 649bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley ALOGE("Could not open selinux status; exiting.\n"); 650bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley exit(1); 651bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 652bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley 65394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood lsocket = android_get_control_socket(SOCKET_PATH); 65494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (lsocket < 0) { 65594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); 65694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 65794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 65894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (listen(lsocket, 5)) { 65994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Listen on socket failed: %s\n", strerror(errno)); 66094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 66194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 66294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(lsocket, F_SETFD, FD_CLOEXEC); 66394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 66494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 66594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood alen = sizeof(addr); 66694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = accept(lsocket, &addr, &alen); 66794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (s < 0) { 66894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Accept failed: %s\n", strerror(errno)); 66994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 67094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 67194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(s, F_SETFD, FD_CLOEXEC); 67294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 67394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("new connection\n"); 67494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 67594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 67694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, &count, sizeof(count))) { 67794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read size\n"); 67894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 67994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 68094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count < 1) || (count >= BUFFER_MAX)) { 68194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("invalid size %d\n", count); 68294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 68394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 68494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, buf, count)) { 68594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read command\n"); 68694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 68794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 68894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood buf[count] = 0; 689bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_updated() > 0) { 690bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley selinux_android_seapp_context_reload(); 691bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 69294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (execute(s, buf)) break; 69394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 69494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("closing connection\n"); 69594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(s); 69694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 69794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 69894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 69994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 70002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 70102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace installd 70202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace android 70302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 70402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampeint main(const int argc, char *argv[]) { 70502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return android::installd::installd_main(argc, argv); 70602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 707