installd.cpp revision d089ca1703769854356a263ca640d3e07ab8548d
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) { 68632350257cd93e34aa1e8b354c1535864b314c38Dan Austin const char *file_name_start; 69632350257cd93e34aa1e8b354c1535864b314c38Dan Austin const 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) { 2102f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags, ino_t ce_data_inode */ 2112f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey return clear_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atol(arg[4])); 212c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 213c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 214c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_destroy_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 2152f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags, ino_t ce_data_inode */ 2162f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey return destroy_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atol(arg[4])); 21794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 21894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 21901ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe// We use otapreopt_chroot to get into the chroot. 22001ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampestatic constexpr const char* kOtaPreopt = "/system/bin/otapreopt_chroot"; 22101ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe 222548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampestatic int do_ota_dexopt(const char* args[DEXOPT_PARAM_COUNT], 223548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 22401ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe // Time to fork and run otapreopt. 22501ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe 22601ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe // Check that the tool exists. 22701ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe struct stat s; 22801ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe if (stat(kOtaPreopt, &s) != 0) { 22901ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe LOG(ERROR) << "Otapreopt chroot tool not found."; 23001ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe return -1; 23173dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 23201ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe 23301ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe pid_t pid = fork(); 23401ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe if (pid == 0) { 235548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe const char* argv[1 + DEXOPT_PARAM_COUNT + 1]; 23601ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe argv[0] = kOtaPreopt; 237548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe 238548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe for (size_t i = 0; i < DEXOPT_PARAM_COUNT; ++i) { 239548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe argv[i + 1] = args[i]; 24001ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe } 241548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe 242548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe argv[DEXOPT_PARAM_COUNT + 1] = nullptr; 24301ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe 24401ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe execv(argv[0], (char * const *)argv); 24501ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe PLOG(ERROR) << "execv(OTAPREOPT_CHROOT) failed"; 24601ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe exit(99); 24773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } else { 24801ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe int res = wait_child(pid); 24901ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe if (res == 0) { 25001ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe ALOGV("DexInv: --- END OTAPREOPT (success) ---\n"); 25101ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe } else { 25201ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe ALOGE("DexInv: --- END OTAPREOPT --- status=0x%04x, process failed\n", res); 25301ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe } 25401ad5984dd202311a7e301c8c771a5d4b7c76136Andreas Gampe return res; 25573dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 25673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe} 25773dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe 258548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampestatic int do_regular_dexopt(const char* args[DEXOPT_PARAM_COUNT], 259548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 260548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe return dexopt(args); 261548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe} 262548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe 263548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampeusing DexoptFn = int (*)(const char* args[DEXOPT_PARAM_COUNT], 264548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe char reply[REPLY_MAX]); 265548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe 26673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampestatic int do_dexopt(char **arg, char reply[REPLY_MAX]) 26794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 268548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe const char* args[DEXOPT_PARAM_COUNT]; 269548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe for (size_t i = 0; i < DEXOPT_PARAM_COUNT; ++i) { 270548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe CHECK(arg[i] != nullptr); 271548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe args[i] = arg[i]; 272548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe } 273548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe 27473dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe int dexopt_flags = atoi(arg[6]); 275548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe DexoptFn dexopt_fn; 27673dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe if ((dexopt_flags & DEXOPT_OTA) != 0) { 277548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe dexopt_fn = do_ota_dexopt; 278548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe } else { 279548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe dexopt_fn = do_regular_dexopt; 28073dae11162aa61396c06cbdb05b954764e944e02Andreas Gampe } 281548bdb930895d8fe6651eaada0bc5739ee5248c8Andreas Gampe return dexopt_fn(args, reply); 2824d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe} 2834d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe 2844d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampestatic int do_merge_profiles(char **arg, char reply[REPLY_MAX]) 2854d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe{ 2864d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe uid_t uid = static_cast<uid_t>(atoi(arg[0])); 2874d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe const char* pkgname = arg[1]; 2884d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe if (merge_profiles(uid, pkgname)) { 2894d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe strncpy(reply, "true", REPLY_MAX); 2904d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe } else { 2914d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe strncpy(reply, "false", REPLY_MAX); 2924d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe } 2934d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe return 0; 29494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 29594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 2966727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehrstatic int do_dump_profiles(char **arg, char reply[REPLY_MAX]) 2976727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr{ 2986727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr uid_t uid = static_cast<uid_t>(atoi(arg[0])); 2996727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr const char* pkgname = arg[1]; 3006727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr const char* dex_files = arg[2]; 3016727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr if (dump_profile(uid, pkgname, dex_files)) { 3026727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr strncpy(reply, "true", REPLY_MAX); 3036727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr } else { 3046727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr strncpy(reply, "false", REPLY_MAX); 3056727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr } 3066727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr return 0; 3076727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr} 3086727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr 30902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 310091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath{ 311091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath return mark_boot_complete(arg[0] /* instruction set */); 312091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath} 313091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath 31402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3161b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath return rm_dex(arg[0], arg[1]); /* pkgname, instruction_set */ 31794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 31894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_free_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) /* TODO int:free_size */ 32094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3216fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return free_cache(parse_null(arg[0]), (int64_t)atoll(arg[1])); /* uuid, free_size */ 32294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 32394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 324c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_get_app_size(char **arg, char reply[REPLY_MAX]) { 32594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t codesize = 0; 32694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t datasize = 0; 32794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t cachesize = 0; 32894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t asecsize = 0; 32994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = 0; 33094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3312f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey /* const char *uuid, const char *pkgname, int userid, int flags, ino_t ce_data_inode, 3322f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey const char* code_path */ 3332f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey res = get_app_size(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atol(arg[4]), 3342f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey arg[5], &codesize, &datasize, &cachesize, &asecsize); 33594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* 33794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * Each int64_t can take up 22 characters printed out. Make sure it 33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * doesn't go over REPLY_MAX in the future. 33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 34094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, 34194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood codesize, datasize, cachesize, asecsize); 34294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 34394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 34494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3452f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkeystatic int do_get_app_data_inode(char **arg, char reply[REPLY_MAX]) { 3462f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey ino_t inode = 0; 3472f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey int res = 0; 3482f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey 3492f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey /* const char *uuid, const char *pkgname, int userid, int flags */ 3502f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey res = get_app_data_inode(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), &inode); 3512f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey 3527240a15f8a7eead09a3206baeb3d5eca5346c32fJeff Sharkey snprintf(reply, REPLY_MAX, "%" PRId64, (int64_t) inode); 3532f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey return res; 3542f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey} 3552f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey 356c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_move_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 357c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char* from_uuid, const char *to_uuid, const char *package_name, 358eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis const char *data_app_name, appid_t appid, const char* seinfo, 359eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis int target_sdk_version */ 360eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], 361eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis atoi(arg[4]), arg[5], atoi(arg[6])); 36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 364379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkeystatic int do_create_user_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 365095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee{ 366379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkey /* const char *uuid, userid_t userid, int user_serial, int flags */ 367379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkey return create_user_data(parse_null(arg[0]), atoi(arg[1]), atoi(arg[2]), atoi(arg[3])); 368095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee} 369095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 370379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkeystatic int do_destroy_user_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 372379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkey /* const char *uuid, userid_t userid, int flags */ 373379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkey return destroy_user_data(parse_null(arg[0]), atoi(arg[1]), atoi(arg[2])); 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_linklib(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 37794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 3786fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return linklib(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3])); 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 38102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_idmap(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 38263568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad{ 38363568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad return idmap(arg[0], arg[1], atoi(arg[2])); 38463568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad} 38563568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad 38602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_create_oat_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 38788ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 38888ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir, instruction_set */ 38988ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return create_oat_dir(arg[0], arg[1]); 39088ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov} 39188ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov 39202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_package_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 39388ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 39488ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir */ 39588ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return rm_package_dir(arg[0]); 39643c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light} 39743c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light 398edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravlestatic int do_clear_app_profiles(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 399d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil{ 400d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil /* package_name */ 401edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle return clear_app_profiles(arg[0]); 402edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle} 403edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle 404edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravlestatic int do_destroy_app_profiles(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 405edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle{ 406edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle /* package_name */ 407edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle return destroy_app_profiles(arg[0]); 408d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil} 409d828d6839f6a01e3f0b2b8b2694139dfa801c557David Brazdil 41002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_link_file(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 411d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath{ 412d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath /* relative_path, from_base, to_base */ 413d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath return link_file(arg[0], arg[1], arg[2]); 414d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath} 415d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath 416e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampestatic int do_move_ab(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 417e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe // apk_path, instruction_set, oat_dir 418e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe return move_ab(arg[0], arg[1], arg[2]); 419e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe} 420e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo { 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char *name; 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned numargs; 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int (*func)(char **arg, char reply[REPLY_MAX]); 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo cmds[] = { 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "ping", 0, do_ping }, 429c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 430eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis { "create_app_data", 7, do_create_app_data }, 431c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "restorecon_app_data", 6, do_restorecon_app_data }, 432cc6281cf8146cddb8ace7cbd58c67321639c1520Jeff Sharkey { "migrate_app_data", 4, do_migrate_app_data }, 4332f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey { "clear_app_data", 5, do_clear_app_data }, 4342f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey { "destroy_app_data", 5, do_destroy_app_data }, 435eecb2d205366351af42fd0cd9e1a95de3980764eJanis Danisevskis { "move_complete_app", 7, do_move_complete_app }, 4362f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey { "get_app_size", 6, do_get_app_size }, 4372f720f7ec5c9d0b91defc85878e7330b10f8e89aJeff Sharkey { "get_app_data_inode", 4, do_get_app_data_inode }, 438c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 439379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkey { "create_user_data", 4, do_create_user_data }, 440379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkey { "destroy_user_data", 3, do_destroy_user_data }, 441379a12b0072b322c7f86e690a8e8a220e500861cJeff Sharkey 442b63d91fd2737680351876406277b6c759f4db33cJeff Hao { "dexopt", 10, do_dexopt }, 443091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "markbootcomplete", 1, do_mark_boot_complete }, 4441b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath { "rmdex", 2, do_rm_dex }, 4456fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "freecache", 2, do_free_cache }, 4466fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "linklib", 4, do_linklib }, 44763568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad { "idmap", 3, do_idmap }, 44888ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov { "createoatdir", 2, do_create_oat_dir }, 449d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath { "rmpackagedir", 1, do_rm_package_dir }, 450edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle { "clear_app_profiles", 1, do_clear_app_profiles }, 451edae669f18eb99b9316891fdde627e2f385c3c64Calin Juravle { "destroy_app_profiles", 1, do_destroy_app_profiles }, 452c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "linkfile", 3, do_link_file }, 453e65b4faa798269ab6ee0d27dab03b8b5caa6f956Andreas Gampe { "move_ab", 3, do_move_ab }, 4544d0f825dd76a1972a3d081e771cde28513a1c6ffAndreas Gampe { "merge_profiles", 2, do_merge_profiles }, 4556727c2d0bfc876c62d6ee60d8a05d26bef1d56efDavid Sehr { "dump_profiles", 3, do_dump_profiles }, 45694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int readx(int s, void *_buf, int count) 45994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 46019803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey char *buf = (char *) _buf; 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = read(s, buf + n, count - n); 46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 46794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("read error: %s\n", strerror(errno)); 46894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r == 0) { 47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("eof\n"); 47294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; /* EOF */ 47394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 47794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int writex(int s, const void *_buf, int count) 48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 48119803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey const char *buf = (const char *) _buf; 48294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = write(s, buf + n, count - n); 48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 48794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 48894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("write error: %s\n", strerror(errno)); 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 49094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 49294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Tokenize the command buffer, locate a matching command, 49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * ensure that the required number of arguments are provided, 49994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * call the function(), return the result. 50094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int execute(int s, char cmd[BUFFER_MAX]) 50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char reply[REPLY_MAX]; 50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *arg[TOKEN_MAX+1]; 50594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned i; 50694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned n = 0; 50794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int ret = -1; 50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5101705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("execute('%s')\n", cmd); 51194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* default reply is "" */ 51394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply[0] = 0; 51494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* n is number of args (not counting arg[0]) */ 51694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[0] = cmd; 51794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*cmd) { 51894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (isspace(*cmd)) { 51994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *cmd++ = 0; 52094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n++; 52194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[n] = cmd; 52294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n == TOKEN_MAX) { 52394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("too many arguments\n"); 52494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 52594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52762bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov if (*cmd) { 52862bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov cmd++; 52962bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov } 53094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 53194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 53294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { 53394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!strcmp(cmds[i].name,arg[0])) { 53494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n != cmds[i].numargs) { 53594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("%s requires %d arguments (%d given)\n", 53694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmds[i].name, cmds[i].numargs, n); 53794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 53894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = cmds[i].func(arg + 1, reply); 53994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 54194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 54394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("unsupported command '%s'\n", arg[0]); 54494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddone: 54694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (reply[0]) { 54794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); 54894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 54994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d", ret); 55094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 55194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n > BUFFER_MAX) n = BUFFER_MAX; 55294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood count = n; 55394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 5541705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("reply: '%s'\n", cmd); 55594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, &count, sizeof(count))) return -1; 55694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, cmd, count)) return -1; 55794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 55894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 55994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 560d089ca1703769854356a263ca640d3e07ab8548dAndreas Gampestatic bool initialize_globals() { 56102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* data_path = getenv("ANDROID_DATA"); 56202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (data_path == nullptr) { 56302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_DATA"); 56402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 56594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* root_path = getenv("ANDROID_ROOT"); 56702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (root_path == nullptr) { 56802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_ROOT"); 56902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 57094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 57194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return init_globals_from_data_and_root(data_path, root_path); 57394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 57494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int initialize_directories() { 57694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = -1; 57794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Read current filesystem layout version to handle upgrade paths 57994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char version_path[PATH_MAX]; 58094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path); 58194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 58294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int oldVersion; 58394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_read_atomic_int(version_path, &oldVersion) == -1) { 58494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood oldVersion = 0; 58594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 58694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int version = oldVersion; 58794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 588e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey if (version < 2) { 589e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey SLOGD("Assuming that device has multi-user storage layout; upgrade no longer supported"); 59094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood version = 2; 59194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 59294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59307053fcb61436221fac2281394e98ec9d0feab3dRobin Lee if (ensure_config_user_dirs(0) == -1) { 59407053fcb61436221fac2281394e98ec9d0feab3dRobin Lee ALOGE("Failed to setup misc for user 0"); 59507053fcb61436221fac2281394e98ec9d0feab3dRobin Lee goto fail; 59607053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 59707053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 598095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (version == 2) { 599095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee ALOGD("Upgrading to /data/misc/user directories"); 600095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 60160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_dir[PATH_MAX]; 60260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.path); 60360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 60460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_added_dir[PATH_MAX]; 60560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); 60660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 60760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_removed_dir[PATH_MAX]; 60860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); 60960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 610095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee DIR *dir; 611095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee struct dirent *dirent; 612e02657d627a85628ec6f0f398fb85283b8d91bfaJeff Sharkey dir = opendir("/data/user"); 613095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (dir != NULL) { 614095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee while ((dirent = readdir(dir))) { 61560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee const char *name = dirent->d_name; 616095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 61760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // skip "." and ".." 61860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[0] == '.') { 61960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[1] == 0) continue; 62060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if ((name[1] == '.') && (name[2] == 0)) continue; 62160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 622095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 62360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uint32_t user_id = atoi(name); 62460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 62560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // /data/misc/user/<user_id> 62660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (ensure_config_user_dirs(user_id) == -1) { 62760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee goto fail; 62860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 62960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 63060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_added_dir[PATH_MAX]; 63160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name); 63260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 63360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_removed_dir[PATH_MAX]; 63460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name); 63560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 63660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM); 63760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee gid_t gid = uid; 63860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 63960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) { 64060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 64160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 64260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 64360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 64460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) { 64560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 646095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 647095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 648095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 649095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee closedir(dir); 65007053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 65160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 65260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_added_dir, 1, 0); 65307053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 65460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 65560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_removed_dir, 1, 0); 65607053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 65707053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 658095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 65907053fcb61436221fac2281394e98ec9d0feab3dRobin Lee version = 3; 660095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 661095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 66294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Persist layout version if changed 66394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (version != oldVersion) { 66494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_write_atomic_int(version_path, version) == -1) { 66594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to save version to %s: %s", version_path, strerror(errno)); 66694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 66794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 66894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 66994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 67094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Success! 67194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = 0; 67294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 67394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail: 67494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 67594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 67694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6777abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalleystatic int log_callback(int type, const char *fmt, ...) { 6787abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_list ap; 6797abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley int priority; 6807abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 6817abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley switch (type) { 6827abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_WARNING: 6837abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_WARN; 6847abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6857abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_INFO: 6867abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_INFO; 6877abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6887abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley default: 6897abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_ERROR; 6907abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6917abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley } 6927abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_start(ap, fmt); 6937abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley LOG_PRI_VA(priority, "SELinux", fmt, ap); 6947abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_end(ap); 6957abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley return 0; 6967abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley} 6977abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 69802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { 69994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char buf[BUFFER_MAX]; 70094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct sockaddr addr; 70194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood socklen_t alen; 70299d9fb15b4a1eb534261ae81b2cf25aec4447bd0Chih-Hung Hsieh int lsocket, s; 703bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley int selinux_enabled = (is_selinux_enabled() > 0); 70494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 705e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey setenv("ANDROID_LOG_TAGS", "*:v", 1); 706e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey android::base::InitLogging(argv); 707e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 70894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("installd firing up\n"); 70994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 7107abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley union selinux_callback cb; 7117abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley cb.func_log = log_callback; 7127abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley selinux_set_callback(SELINUX_CB_LOG, cb); 7137abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 71402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (!initialize_globals()) { 71594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not initialize globals; exiting.\n"); 71694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 71794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 71894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 71994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (initialize_directories() < 0) { 72094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not create directories; exiting.\n"); 72194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 72294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 72394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 724bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_open(true) < 0) { 725bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley ALOGE("Could not open selinux status; exiting.\n"); 726bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley exit(1); 727bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 728bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley 72994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood lsocket = android_get_control_socket(SOCKET_PATH); 73094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (lsocket < 0) { 73194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); 73294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 73394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 73494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (listen(lsocket, 5)) { 73594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Listen on socket failed: %s\n", strerror(errno)); 73694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 73794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 73894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(lsocket, F_SETFD, FD_CLOEXEC); 73994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 74094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 74194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood alen = sizeof(addr); 74294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = accept(lsocket, &addr, &alen); 74394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (s < 0) { 74494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Accept failed: %s\n", strerror(errno)); 74594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 74694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 74794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(s, F_SETFD, FD_CLOEXEC); 74894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 74994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("new connection\n"); 75094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 75194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 75294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, &count, sizeof(count))) { 75394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read size\n"); 75494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 75594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 75694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count < 1) || (count >= BUFFER_MAX)) { 75794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("invalid size %d\n", count); 75894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 75994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 76094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, buf, count)) { 76194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read command\n"); 76294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 76394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 76494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood buf[count] = 0; 765bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_updated() > 0) { 766bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley selinux_android_seapp_context_reload(); 767bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 76894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (execute(s, buf)) break; 76994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 77094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("closing connection\n"); 77194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(s); 77294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 77394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 77494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 77594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 77602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 77702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace installd 77802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace android 77902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 78002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampeint main(const int argc, char *argv[]) { 78102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return android::installd::installd_main(argc, argv); 78202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 783