installd.cpp revision c7d1b2250e8245a7e4e144758bc3ccd33b8d6319
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 48c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey#define DEBUG_FBE 0 4902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 5002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampenamespace android { 5102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampenamespace installd { 5202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 5302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe// Check that installd-deps sizes match cutils sizes. 5402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic_assert(kPropertyKeyMax == PROPERTY_KEY_MAX, "Size mismatch."); 5502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic_assert(kPropertyValueMax == PROPERTY_VALUE_MAX, "Size mismatch."); 5602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 5702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe//////////////////////// 5802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe// Plug-in functions. // 5902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe//////////////////////// 6002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 6102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampeint get_property(const char *key, char *value, const char *default_value) { 6202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return property_get(key, value, default_value); 6302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 6402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 6502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe// Compute the output path of 6602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool calculate_oat_file_path(char path[PKG_PATH_MAX], 6702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *oat_dir, 6802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *apk_path, 6902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *instruction_set) { 7002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char *file_name_start; 7102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char *file_name_end; 7202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 7302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe file_name_start = strrchr(apk_path, '/'); 7402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (file_name_start == NULL) { 7502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it\n", apk_path); 7602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 7702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 7802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe file_name_end = strrchr(apk_path, '.'); 7902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (file_name_end < file_name_start) { 8002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no extension\n", apk_path); 8102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 8202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 8302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 8402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe // Calculate file_name 8502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe int file_name_len = file_name_end - file_name_start - 1; 8602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char file_name[file_name_len + 1]; 8702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe memcpy(file_name, file_name_start + 1, file_name_len); 8802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe file_name[file_name_len] = '\0'; 8902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 9002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe // <apk_parent_dir>/oat/<isa>/<file_name>.odex 9102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe snprintf(path, PKG_PATH_MAX, "%s/%s/%s.odex", oat_dir, instruction_set, file_name); 9202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return true; 9302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 9402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 9502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe/* 9602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * Computes the odex file for the given apk_path and instruction_set. 9702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * /system/framework/whatever.jar -> /system/framework/oat/<isa>/whatever.odex 9802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * 9902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe * Returns false if it failed to determine the odex file path. 10002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe */ 10102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool calculate_odex_file_path(char path[PKG_PATH_MAX], 10202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *apk_path, 10302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *instruction_set) { 10402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (strlen(apk_path) + strlen("oat/") + strlen(instruction_set) 10502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe + strlen("/") + strlen("odex") + 1 > PKG_PATH_MAX) { 10602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' may be too long to form odex file path.\n", apk_path); 10702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 10802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 10902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 11002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcpy(path, apk_path); 11102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char *end = strrchr(path, '/'); 11202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (end == NULL) { 11302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no '/'s in it?!\n", apk_path); 11402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 11502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 11602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *apk_end = apk_path + (end - path); // strrchr(apk_path, '/'); 11702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 11802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcpy(end + 1, "oat/"); // path = /system/framework/oat/\0 11902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcat(path, instruction_set); // path = /system/framework/oat/<isa>\0 12002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcat(path, apk_end); // path = /system/framework/oat/<isa>/whatever.jar\0 12102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe end = strrchr(path, '.'); 12202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (end == NULL) { 12302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("apk_path '%s' has no extension.\n", apk_path); 12402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 12502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 12602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strcpy(end + 1, "odex"); 12702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return true; 12802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 12902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 13002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool create_cache_path(char path[PKG_PATH_MAX], 13102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *src, 13202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char *instruction_set) { 13302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe size_t srclen = strlen(src); 13402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 13502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe /* demand that we are an absolute path */ 13602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if ((src == 0) || (src[0] != '/') || strstr(src,"..")) { 13702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 13802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 13902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 14002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (srclen > PKG_PATH_MAX) { // XXX: PKG_NAME_MAX? 14102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 14202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 14302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 14402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe size_t dstlen = 14502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe android_data_dir.len + 14602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(DALVIK_CACHE) + 14702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 1 + 14802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(instruction_set) + 14902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe srclen + 15002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(DALVIK_CACHE_POSTFIX) + 2; 15102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 15202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (dstlen > PKG_PATH_MAX) { 15302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 15402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 15502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 15602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe sprintf(path,"%s%s/%s/%s%s", 15702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe android_data_dir.path, 15802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe DALVIK_CACHE, 15902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe instruction_set, 16002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe src + 1, /* skip the leading / */ 16102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe DALVIK_CACHE_POSTFIX); 16202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 16302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe char* tmp = 16402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe path + 16502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe android_data_dir.len + 16602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(DALVIK_CACHE) + 16702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 1 + 16802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe strlen(instruction_set) + 1; 16902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 17002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe for(; *tmp; tmp++) { 17102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (*tmp == '/') { 17202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe *tmp = '@'; 17302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 17402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe } 17502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 17602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return true; 17702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 17802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 17902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 1806fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkeystatic char* parse_null(char* arg) { 1816fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey if (strcmp(arg, "!") == 0) { 1826fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return nullptr; 1836fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey } else { 1846fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return arg; 1856fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey } 1866fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey} 1876fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey 18802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_ping(char **arg ATTRIBUTE_UNUSED, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 18994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 19094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 19194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 19294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 193c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_create_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 194c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags, 195c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey appid_t appid, const char* seinfo */ 196c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return create_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]); 197c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 198c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 199c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_restorecon_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 200c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char* uuid, const char* pkgName, userid_t userid, int flags, 201c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey appid_t appid, const char* seinfo */ 202c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return restorecon_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), atoi(arg[4]), arg[5]); 203c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 204c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 205c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_clear_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 206c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags */ 207c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return clear_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); 208c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey} 209c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 210c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_destroy_app_data(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 211c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags */ 212c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return destroy_app_data(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3])); 21394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 21494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 21502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_dexopt(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 21694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 21776e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy /* apk_path, uid, pkgname, instruction_set, dexopt_needed, oat_dir, dexopt_flags */ 21876e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy return dexopt(arg[0], atoi(arg[1]), arg[2], arg[3], atoi(arg[4]), 21976e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy arg[5], atoi(arg[6])); 22094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 22194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 22202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_mark_boot_complete(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 223091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath{ 224091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath return mark_boot_complete(arg[0] /* instruction set */); 225091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath} 226091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath 22702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_dex(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 22894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2291b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath return rm_dex(arg[0], arg[1]); /* pkgname, instruction_set */ 23094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 23194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 23202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_free_cache(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) /* TODO int:free_size */ 23394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2346fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return free_cache(parse_null(arg[0]), (int64_t)atoll(arg[1])); /* uuid, free_size */ 23594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 23694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 237c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_get_app_size(char **arg, char reply[REPLY_MAX]) { 23894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t codesize = 0; 23994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t datasize = 0; 24094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t cachesize = 0; 24194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int64_t asecsize = 0; 24294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = 0; 24394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 244c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char *uuid, const char *pkgname, userid_t userid, int flags, 245c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey const char *apkpath, const char *libdirpath, const char *fwdlock_apkpath, 246c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey const char *asecpath, const char *instruction_set */ 247c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey res = get_app_size(parse_null(arg[0]), arg[1], atoi(arg[2]), atoi(arg[3]), arg[4], arg[5], 248c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey arg[6], arg[7], arg[8], &codesize, &datasize, &cachesize, &asecsize); 24994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 25094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* 25194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * Each int64_t can take up 22 characters printed out. Make sure it 25294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * doesn't go over REPLY_MAX in the future. 25394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 25494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, 25594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood codesize, datasize, cachesize, asecsize); 25694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 25794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 25894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 259c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkeystatic int do_move_complete_app(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) { 260c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey /* const char* from_uuid, const char *to_uuid, const char *package_name, 261c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey const char *data_app_name, appid_t appid, const char* seinfo */ 262c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey return move_complete_app(parse_null(arg[0]), parse_null(arg[1]), arg[2], arg[3], atoi(arg[4]), arg[5]); 26394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 26494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 26502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_mk_user_config(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 266095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee{ 2677c8bec01790087748ec7afa69a31789828b751f9Robin Lee return make_user_config(atoi(arg[0])); /* userid */ 268095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee} 269095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 27002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_user(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 27194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2726fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return delete_user(parse_null(arg[0]), atoi(arg[1])); /* uuid, userid */ 27394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 27494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 27502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_movefiles(char **arg ATTRIBUTE_UNUSED, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 27694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 27794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return movefiles(); 27894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 27994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_linklib(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 28194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 2826fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey return linklib(parse_null(arg[0]), arg[1], arg[2], atoi(arg[3])); 28394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 28494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 28502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_idmap(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 28663568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad{ 28763568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad return idmap(arg[0], arg[1], atoi(arg[2])); 28863568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad} 28963568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad 29002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_create_oat_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 29188ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 29288ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir, instruction_set */ 29388ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return create_oat_dir(arg[0], arg[1]); 29488ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov} 29588ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov 29602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_rm_package_dir(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 29788ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov{ 29888ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov /* oat_dir */ 29988ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov return rm_package_dir(arg[0]); 30043c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light} 30143c5d30795faf08ab639b8d88c2eceaf2b648c93Alex Light 30202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int do_link_file(char **arg, char reply[REPLY_MAX] ATTRIBUTE_UNUSED) 303d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath{ 304d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath /* relative_path, from_base, to_base */ 305d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath return link_file(arg[0], arg[1], arg[2]); 306d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath} 307d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath 30894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo { 30994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char *name; 31094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned numargs; 31194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int (*func)(char **arg, char reply[REPLY_MAX]); 31294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 31394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 31494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstruct cmdinfo cmds[] = { 31594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "ping", 0, do_ping }, 316c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 317c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "create_app_data", 6, do_create_app_data }, 318c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "restorecon_app_data", 6, do_restorecon_app_data }, 319c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "clear_app_data", 4, do_clear_app_data }, 320c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "destroy_app_data", 4, do_destroy_app_data }, 321c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "move_complete_app", 6, do_move_complete_app }, 322c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "get_app_size", 9, do_get_app_size }, 323c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 32476e767ca14bcbb4bc809cd1279ece82a3aabe8a4Todd Kennedy { "dexopt", 7, do_dexopt }, 325091ea779d4e575856c04d51d82f45cc8a6155b5eNarayan Kamath { "markbootcomplete", 1, do_mark_boot_complete }, 3261b4003207750ea8fe8c7b03eb32d80f1df83979eNarayan Kamath { "rmdex", 2, do_rm_dex }, 3276fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "freecache", 2, do_free_cache }, 32894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood { "movefiles", 0, do_movefiles }, 3296fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "linklib", 4, do_linklib }, 3307c8bec01790087748ec7afa69a31789828b751f9Robin Lee { "mkuserconfig", 1, do_mk_user_config }, 3316fe28a06012250da85f808a0869f87e06e0bcce9Jeff Sharkey { "rmuser", 2, do_rm_user }, 33263568b1430d741f40ca008391c854ef1cc880138MÃ¥rten Kongstad { "idmap", 3, do_idmap }, 33388ce4ff7a95ea2008fa28f12b880ee526e331440Fyodor Kupolov { "createoatdir", 2, do_create_oat_dir }, 334d845c96128a40ca5802c0840ae190fa0af7d4735Narayan Kamath { "rmpackagedir", 1, do_rm_package_dir }, 335c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey { "linkfile", 3, do_link_file }, 33694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood}; 33794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 33894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int readx(int s, void *_buf, int count) 33994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 34019803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey char *buf = (char *) _buf; 34194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 34294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 34394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 34494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = read(s, buf + n, count - n); 34594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 34694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 34794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("read error: %s\n", strerror(errno)); 34894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 34994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r == 0) { 35194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("eof\n"); 35294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; /* EOF */ 35394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 35594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 35694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 35794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 35894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 35994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int writex(int s, const void *_buf, int count) 36094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 36119803807cd7ae01868fcfa50305f4a7dd13765e2Jeff Sharkey const char *buf = (const char *) _buf; 36294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int n = 0, r; 36394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (count < 0) return -1; 36494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (n < count) { 36594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood r = write(s, buf + n, count - n); 36694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (r < 0) { 36794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (errno == EINTR) continue; 36894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("write error: %s\n", strerror(errno)); 36994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return -1; 37094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 37194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n += r; 37294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 37394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 37494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 37594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 37794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood/* Tokenize the command buffer, locate a matching command, 37894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * ensure that the required number of arguments are provided, 37994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood * call the function(), return the result. 38094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood */ 38194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodstatic int execute(int s, char cmd[BUFFER_MAX]) 38294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood{ 38394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char reply[REPLY_MAX]; 38494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *arg[TOKEN_MAX+1]; 38594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned i; 38694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned n = 0; 38794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 38894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int ret = -1; 38994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 3901705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("execute('%s')\n", cmd); 39194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 39294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* default reply is "" */ 39394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood reply[0] = 0; 39494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 39594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood /* n is number of args (not counting arg[0]) */ 39694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[0] = cmd; 39794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while (*cmd) { 39894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (isspace(*cmd)) { 39994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood *cmd++ = 0; 40094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n++; 40194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood arg[n] = cmd; 40294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n == TOKEN_MAX) { 40394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("too many arguments\n"); 40494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 40594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 40694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 40762bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov if (*cmd) { 40862bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov cmd++; 40962bb385728121b456782d205f6e27d0c18be9c0bSerguei Katkov } 41094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 41194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 41294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { 41394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!strcmp(cmds[i].name,arg[0])) { 41494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n != cmds[i].numargs) { 41594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("%s requires %d arguments (%d given)\n", 41694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood cmds[i].name, cmds[i].numargs, n); 41794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 41894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ret = cmds[i].func(arg + 1, reply); 41994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 42094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto done; 42194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 42294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 42394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("unsupported command '%s'\n", arg[0]); 42494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 42594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwooddone: 42694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (reply[0]) { 42794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); 42894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } else { 42994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood n = snprintf(cmd, BUFFER_MAX, "%d", ret); 43094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 43194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (n > BUFFER_MAX) n = BUFFER_MAX; 43294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood count = n; 43394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 4341705fc44fb85c4232637f9f7189c3bdca98a63d5Brian Carlstrom // ALOGI("reply: '%s'\n", cmd); 43594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, &count, sizeof(count))) return -1; 43694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (writex(s, cmd, count)) return -1; 43794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 43894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 43994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 44002d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampebool initialize_globals() { 44102d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* data_path = getenv("ANDROID_DATA"); 44202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (data_path == nullptr) { 44302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_DATA"); 44402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 44594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 44602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe const char* root_path = getenv("ANDROID_ROOT"); 44702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (root_path == nullptr) { 44802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe ALOGE("Could not find ANDROID_ROOT"); 44902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return false; 45094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 45194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45202d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return init_globals_from_data_and_root(data_path, root_path); 45394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 45494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int initialize_directories() { 45694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int res = -1; 45794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 45894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Read current filesystem layout version to handle upgrade paths 45994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char version_path[PATH_MAX]; 46094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path); 46194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int oldVersion; 46394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_read_atomic_int(version_path, &oldVersion) == -1) { 46494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood oldVersion = 0; 46594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 46694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood int version = oldVersion; 46794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 46894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/user 46994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *user_data_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX); 47094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/data 47194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *legacy_data_dir = build_string2(android_data_dir.path, PRIMARY_USER_PREFIX); 47294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/user/0 47394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char *primary_data_dir = build_string3(android_data_dir.path, SECONDARY_USER_PREFIX, "0"); 47494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (!user_data_dir || !legacy_data_dir || !primary_data_dir) { 47594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 47694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 47794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 47894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Make the /data/user directory if necessary 47994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (access(user_data_dir, R_OK) < 0) { 48094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (mkdir(user_data_dir, 0711) < 0) { 48194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 48294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 48394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) { 48494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 48594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 48694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (chmod(user_data_dir, 0711) < 0) { 48794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 48894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 48994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Make the /data/user/0 symlink to /data/data if necessary 49194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (access(primary_data_dir, R_OK) < 0) { 49294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (symlink(legacy_data_dir, primary_data_dir)) { 49394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 49494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 49694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 49794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (version == 0) { 49894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Introducing multi-user, so migrate /data/media contents into /data/media/0 49994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGD("Upgrading /data/media for multi-user"); 50094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Ensure /data/media 50294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 50394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 50494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 50594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 50694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/media.tmp 50794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char media_tmp_dir[PATH_MAX]; 50894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(media_tmp_dir, PATH_MAX, "%smedia.tmp", android_data_dir.path); 50994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Only copy when upgrade not already in progress 51194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (access(media_tmp_dir, F_OK) == -1) { 51294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (rename(android_media_dir.path, media_tmp_dir) == -1) { 51394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to move legacy media path: %s", strerror(errno)); 51494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 51594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 51794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 51894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Create /data/media again 51994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 52094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 52194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 52294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 52326288202e7bdf2e897a11bf31a15685d7c20945fStephen Smalley if (selinux_android_restorecon(android_media_dir.path, 0)) { 52447a351834f202386b01a27d42ec41ceb1f17b754Stephen Smalley goto fail; 52547a351834f202386b01a27d42ec41ceb1f17b754Stephen Smalley } 52647a351834f202386b01a27d42ec41ceb1f17b754Stephen Smalley 52794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/media/0 52894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char owner_media_dir[PATH_MAX]; 52994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(owner_media_dir, PATH_MAX, "%s0", android_media_dir.path); 53094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 53194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Move any owner data into place 53294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (access(media_tmp_dir, F_OK) == 0) { 53394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (rename(media_tmp_dir, owner_media_dir) == -1) { 53494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to move owner media path: %s", strerror(errno)); 53594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 53694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 53794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 53894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 53994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Ensure media directories for any existing users 54094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood DIR *dir; 54194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct dirent *dirent; 54294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char user_media_dir[PATH_MAX]; 54394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 54494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood dir = opendir(user_data_dir); 54594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (dir != NULL) { 54694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood while ((dirent = readdir(dir))) { 54794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (dirent->d_type == DT_DIR) { 54894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood const char *name = dirent->d_name; 54994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // skip "." and ".." 55194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (name[0] == '.') { 55294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (name[1] == 0) continue; 55394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((name[1] == '.') && (name[2] == 0)) continue; 55494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 55594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 55694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/media/<user_id> 55794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(user_media_dir, PATH_MAX, "%s%s", android_media_dir.path, name); 55894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_prepare_dir(user_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 55994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 56094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood closedir(dir); 56494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 56694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood version = 1; 56794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 56894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 56994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/media/obb 57094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char media_obb_dir[PATH_MAX]; 57194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(media_obb_dir, PATH_MAX, "%sobb", android_media_dir.path); 57294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (version == 1) { 57494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Introducing /data/media/obb for sharing OBB across users; migrate 57594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // any existing OBB files from owner. 57694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGD("Upgrading to shared /data/media/obb"); 57794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 57894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // /data/media/0/Android/obb 57994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char owner_obb_path[PATH_MAX]; 58094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood snprintf(owner_obb_path, PATH_MAX, "%s0/Android/obb", android_media_dir.path); 58194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 58294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Only move if target doesn't already exist 58394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (access(media_obb_dir, F_OK) != 0 && access(owner_obb_path, F_OK) == 0) { 58494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (rename(owner_obb_path, media_obb_dir) == -1) { 58594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to move OBB from owner: %s", strerror(errno)); 58694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 58794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 58894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 58994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood version = 2; 59194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 59294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 59341ea424413c0381ef2aa15fc5bd5d4b88abd23c4Jeff Sharkey if (ensure_media_user_dirs(nullptr, 0) == -1) { 59494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to setup media for user 0"); 59594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 59694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 59794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_prepare_dir(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 59894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 59994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 60094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 60107053fcb61436221fac2281394e98ec9d0feab3dRobin Lee if (ensure_config_user_dirs(0) == -1) { 60207053fcb61436221fac2281394e98ec9d0feab3dRobin Lee ALOGE("Failed to setup misc for user 0"); 60307053fcb61436221fac2281394e98ec9d0feab3dRobin Lee goto fail; 60407053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 60507053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 606095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (version == 2) { 607095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee ALOGD("Upgrading to /data/misc/user directories"); 608095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 60960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_dir[PATH_MAX]; 61060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_dir, PATH_MAX, "%smisc", android_data_dir.path); 61160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 61260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_added_dir[PATH_MAX]; 61360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_added_dir, PATH_MAX, "%s/keychain/cacerts-added", misc_dir); 61460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 61560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char keychain_removed_dir[PATH_MAX]; 61660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(keychain_removed_dir, PATH_MAX, "%s/keychain/cacerts-removed", misc_dir); 61760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 618095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee DIR *dir; 619095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee struct dirent *dirent; 620095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee dir = opendir(user_data_dir); 621095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee if (dir != NULL) { 622095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee while ((dirent = readdir(dir))) { 62360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee const char *name = dirent->d_name; 624095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 62560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // skip "." and ".." 62660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[0] == '.') { 62760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (name[1] == 0) continue; 62860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if ((name[1] == '.') && (name[2] == 0)) continue; 62960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 630095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 63160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uint32_t user_id = atoi(name); 63260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 63360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee // /data/misc/user/<user_id> 63460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (ensure_config_user_dirs(user_id) == -1) { 63560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee goto fail; 63660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 63760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 63860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_added_dir[PATH_MAX]; 63960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_added_dir, PATH_MAX, "%s/user/%s/cacerts-added", misc_dir, name); 64060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 64160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee char misc_removed_dir[PATH_MAX]; 64260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee snprintf(misc_removed_dir, PATH_MAX, "%s/user/%s/cacerts-removed", misc_dir, name); 64360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee 64460fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee uid_t uid = multiuser_get_uid(user_id, AID_SYSTEM); 64560fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee gid_t gid = uid; 64660fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 64760fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_added_dir, misc_added_dir, uid, gid) != 0) { 64860fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 64960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 65060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee } 65160fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 65260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (copy_dir_files(keychain_removed_dir, misc_removed_dir, uid, gid) != 0) { 65360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee ALOGE("Some files failed to copy"); 654095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 655095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 656095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 657095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee closedir(dir); 65807053fcb61436221fac2281394e98ec9d0feab3dRobin Lee 65960fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_added_dir, F_OK) == 0) { 66060fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_added_dir, 1, 0); 66107053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 66260fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee if (access(keychain_removed_dir, F_OK) == 0) { 66360fd3feecab4336d964ca8e31c7c3220e1afb558Robin Lee delete_dir_contents(keychain_removed_dir, 1, 0); 66407053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 66507053fcb61436221fac2281394e98ec9d0feab3dRobin Lee } 666095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 66707053fcb61436221fac2281394e98ec9d0feab3dRobin Lee version = 3; 668095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee } 669095c763dd9aa26a206d10ab7c1d7e1c569298fb3Robin Lee 67094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Persist layout version if changed 67194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (version != oldVersion) { 67294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (fs_write_atomic_int(version_path, version) == -1) { 67394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to save version to %s: %s", version_path, strerror(errno)); 67494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood goto fail; 67594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 67694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 67794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 67894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood // Success! 67994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood res = 0; 68094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 68194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwoodfail: 68294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(user_data_dir); 68394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(legacy_data_dir); 68494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood free(primary_data_dir); 68594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return res; 68694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 68794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 6887abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalleystatic int log_callback(int type, const char *fmt, ...) { 6897abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_list ap; 6907abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley int priority; 6917abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 6927abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley switch (type) { 6937abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_WARNING: 6947abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_WARN; 6957abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6967abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley case SELINUX_INFO: 6977abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_INFO; 6987abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 6997abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley default: 7007abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley priority = ANDROID_LOG_ERROR; 7017abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley break; 7027abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley } 7037abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_start(ap, fmt); 7047abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley LOG_PRI_VA(priority, "SELinux", fmt, ap); 7057abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley va_end(ap); 7067abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley return 0; 7077abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley} 7087abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 70902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampestatic int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) { 71094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood char buf[BUFFER_MAX]; 71194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood struct sockaddr addr; 71294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood socklen_t alen; 71399d9fb15b4a1eb534261ae81b2cf25aec4447bd0Chih-Hung Hsieh int lsocket, s; 714bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley int selinux_enabled = (is_selinux_enabled() > 0); 71594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 716e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey setenv("ANDROID_LOG_TAGS", "*:v", 1); 717e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey android::base::InitLogging(argv); 718e36372423000a906bafae68844ebc6c42d09335aJeff Sharkey 71994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("installd firing up\n"); 72094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 7217abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley union selinux_callback cb; 7227abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley cb.func_log = log_callback; 7237abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley selinux_set_callback(SELINUX_CB_LOG, cb); 7247abb52bcafa2f7b422dfe22c5ea275c2fa9e6201Stephen Smalley 72502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe if (!initialize_globals()) { 72694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not initialize globals; exiting.\n"); 72794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 72894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 72994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 73094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (initialize_directories() < 0) { 73194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Could not create directories; exiting.\n"); 73294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 73394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 73494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 735bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_open(true) < 0) { 736bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley ALOGE("Could not open selinux status; exiting.\n"); 737bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley exit(1); 738bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 739bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley 74094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood lsocket = android_get_control_socket(SOCKET_PATH); 74194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (lsocket < 0) { 74294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); 74394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 74494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 74594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (listen(lsocket, 5)) { 74694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Listen on socket failed: %s\n", strerror(errno)); 74794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood exit(1); 74894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 74994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(lsocket, F_SETFD, FD_CLOEXEC); 75094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 751c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey // Perform all filesystem access as system so that FBE emulation mode 752c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey // can block access using chmod 000. 753c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey#if DEBUG_FBE 754c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey setfsuid(AID_SYSTEM); 755c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey#endif 756c7d1b2250e8245a7e4e144758bc3ccd33b8d6319Jeff Sharkey 75794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 75894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood alen = sizeof(addr); 75994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood s = accept(lsocket, &addr, &alen); 76094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (s < 0) { 76194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("Accept failed: %s\n", strerror(errno)); 76294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood continue; 76394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 76494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood fcntl(s, F_SETFD, FD_CLOEXEC); 76594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 76694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("new connection\n"); 76794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood for (;;) { 76894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood unsigned short count; 76994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, &count, sizeof(count))) { 77094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read size\n"); 77194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 77294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 77394afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if ((count < 1) || (count >= BUFFER_MAX)) { 77494afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("invalid size %d\n", count); 77594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 77694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 77794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (readx(s, buf, count)) { 77894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGE("failed to read command\n"); 77994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood break; 78094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 78194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood buf[count] = 0; 782bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley if (selinux_enabled && selinux_status_updated() > 0) { 783bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley selinux_android_seapp_context_reload(); 784bd558d61871218f5b13df2fe4b7cc3b530ee947cStephen Smalley } 78594afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood if (execute(s, buf)) break; 78694afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 78794afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood ALOGI("closing connection\n"); 78894afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood close(s); 78994afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood } 79094afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood 79194afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood return 0; 79294afecf4b6f437b3ee9a076242402e421c6c07a6Mike Lockwood} 79302d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 79402d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace installd 79502d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} // namespace android 79602d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe 79702d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampeint main(const int argc, char *argv[]) { 79802d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe return android::installd::installd_main(argc, argv); 79902d0de56c75347a0cb8d5a8565dc8c4ee7616057Andreas Gampe} 800