19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2008, The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich#include <linux/capability.h> 18812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich#include <linux/prctl.h> 19812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "installd.h" 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BUFFER_MAX 1024 /* input buffer for commands */ 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define TOKEN_MAX 8 /* max number of arguments in buffer */ 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define REPLY_MAX 256 /* largest reply allowed */ 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_ping(char **arg, char reply[REPLY_MAX]) 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_install(char **arg, char reply[REPLY_MAX]) 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3435ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root return install(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */ 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_dexopt(char **arg, char reply[REPLY_MAX]) 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* apk_path, uid, is_public */ 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return dexopt(arg[0], atoi(arg[1]), atoi(arg[2])); 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_move_dex(char **arg, char reply[REPLY_MAX]) 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return move_dex(arg[0], arg[1]); /* src, dst */ 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_rm_dex(char **arg, char reply[REPLY_MAX]) 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return rm_dex(arg[0]); /* pkgname */ 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_remove(char **arg, char reply[REPLY_MAX]) 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 550b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return uninstall(arg[0], atoi(arg[1])); /* pkgname, userid */ 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 58b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackbornstatic int do_rename(char **arg, char reply[REPLY_MAX]) 59b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn{ 6035ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root return renamepkg(arg[0], arg[1]); /* oldpkgname, newpkgname */ 61b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn} 62b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 63d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackbornstatic int do_fixuid(char **arg, char reply[REPLY_MAX]) 64d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn{ 65d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn return fix_uid(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */ 66d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn} 67d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_free_cache(char **arg, char reply[REPLY_MAX]) /* TODO int:free_size */ 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 703e319a9962434e1fae86b2180ad210170f02c152Kenny Root return free_cache((int64_t)atoll(arg[0])); /* free_size */ 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_rm_cache(char **arg, char reply[REPLY_MAX]) 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7554289b8b4a110cc1ae106d79785cc762a2aebd6eAmith Yamasani return delete_cache(arg[0], atoi(arg[1])); /* pkgname, userid */ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_get_size(char **arg, char reply[REPLY_MAX]) 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 803e319a9962434e1fae86b2180ad210170f02c152Kenny Root int64_t codesize = 0; 813e319a9962434e1fae86b2180ad210170f02c152Kenny Root int64_t datasize = 0; 823e319a9962434e1fae86b2180ad210170f02c152Kenny Root int64_t cachesize = 0; 83292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn int64_t asecsize = 0; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int res = 0; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 860c3804950236fe170ebf6cc7a5f1e3e305b8f315Dianne Hackborn /* pkgdir, persona, apkpath */ 870c3804950236fe170ebf6cc7a5f1e3e305b8f315Dianne Hackborn res = get_size(arg[0], atoi(arg[1]), arg[2], arg[3], arg[4], 880c3804950236fe170ebf6cc7a5f1e3e305b8f315Dianne Hackborn &codesize, &datasize, &cachesize, &asecsize); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 903e319a9962434e1fae86b2180ad210170f02c152Kenny Root /* 913e319a9962434e1fae86b2180ad210170f02c152Kenny Root * Each int64_t can take up 22 characters printed out. Make sure it 923e319a9962434e1fae86b2180ad210170f02c152Kenny Root * doesn't go over REPLY_MAX in the future. 933e319a9962434e1fae86b2180ad210170f02c152Kenny Root */ 94292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, 95292f8bc9d1b790ab975a87a842c7fabc908b97e0Dianne Hackborn codesize, datasize, cachesize, asecsize); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return res; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int do_rm_user_data(char **arg, char reply[REPLY_MAX]) 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1010b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return delete_user_data(arg[0], atoi(arg[1])); /* pkgname, userid */ 1020b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani} 1030b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 1040b285499db739ba50f2f839d633e763c70e67f96Amith Yamasanistatic int do_mk_user_data(char **arg, char reply[REPLY_MAX]) 1050b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani{ 1060b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return make_user_data(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, userid */ 1070b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani} 1080b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 1090b285499db739ba50f2f839d633e763c70e67f96Amith Yamasanistatic int do_rm_user(char **arg, char reply[REPLY_MAX]) 1100b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani{ 1110b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani return delete_persona(atoi(arg[0])); /* userid */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 114742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasanistatic int do_clone_user_data(char **arg, char reply[REPLY_MAX]) 115742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani{ 116742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani return clone_persona_data(atoi(arg[0]), atoi(arg[1]), atoi(arg[2])); 117742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani} 118742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani 119b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackbornstatic int do_movefiles(char **arg, char reply[REPLY_MAX]) 120b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn{ 121b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn return movefiles(); 122b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn} 123b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn 1246a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Rootstatic int do_linklib(char **arg, char reply[REPLY_MAX]) 1256a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root{ 126a3e90798b7ad3ed62e5b31842c699b2f98bd457bKenny Root return linklib(arg[0], arg[1], atoi(arg[2])); 1276a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root} 1286a6b007c77e5cab7ee435506a4f65824f52028b6Kenny Root 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct cmdinfo { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char *name; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned numargs; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int (*func)(char **arg, char reply[REPLY_MAX]); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct cmdinfo cmds[] = { 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "ping", 0, do_ping }, 13735ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root { "install", 3, do_install }, 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "dexopt", 3, do_dexopt }, 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "movedex", 2, do_move_dex }, 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "rmdex", 1, do_rm_dex }, 1410b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "remove", 2, do_remove }, 14235ab3ad61fcc349380d7e7f2fcf9a0dfbf76ae11Kenny Root { "rename", 2, do_rename }, 143d0c5f515c05d05c9d24971695337daf9d6ce409cDianne Hackborn { "fixuid", 3, do_fixuid }, 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "freecache", 1, do_free_cache }, 14554289b8b4a110cc1ae106d79785cc762a2aebd6eAmith Yamasani { "rmcache", 2, do_rm_cache }, 1460c3804950236fe170ebf6cc7a5f1e3e305b8f315Dianne Hackborn { "getsize", 5, do_get_size }, 1470b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "rmuserdata", 2, do_rm_user_data }, 148b858dfda5012a1040927ed62c3bb856c3294d882Dianne Hackborn { "movefiles", 0, do_movefiles }, 149a3e90798b7ad3ed62e5b31842c699b2f98bd457bKenny Root { "linklib", 3, do_linklib }, 1500b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "mkuserdata", 3, do_mk_user_data }, 1510b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani { "rmuser", 1, do_rm_user }, 152742a67127366c376fdf188ff99ba30b27d3bf90cAmith Yamasani { "cloneuserdata", 3, do_clone_user_data }, 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int readx(int s, void *_buf, int count) 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *buf = _buf; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = 0, r; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 0) return -1; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (n < count) { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = read(s, buf + n, count - n); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r < 0) { 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (errno == EINTR) continue; 1643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("read error: %s\n", strerror(errno)); 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r == 0) { 1683762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("eof\n"); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; /* EOF */ 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += r; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int writex(int s, const void *_buf, int count) 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const char *buf = _buf; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int n = 0, r; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (count < 0) return -1; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (n < count) { 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project r = write(s, buf + n, count - n); 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (r < 0) { 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (errno == EINTR) continue; 1853762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("write error: %s\n", strerror(errno)); 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n += r; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* Tokenize the command buffer, locate a matching command, 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ensure that the required number of arguments are provided, 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * call the function(), return the result. 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic int execute(int s, char cmd[BUFFER_MAX]) 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char reply[REPLY_MAX]; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char *arg[TOKEN_MAX+1]; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned i; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned n = 0; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned short count; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int ret = -1; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2076215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block// ALOGI("execute('%s')\n", cmd); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* default reply is "" */ 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project reply[0] = 0; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* n is number of args (not counting arg[0]) */ 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arg[0] = cmd; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (*cmd) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isspace(*cmd)) { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project *cmd++ = 0; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n++; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project arg[n] = cmd; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n == TOKEN_MAX) { 2203762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("too many arguments\n"); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmd++; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!strcmp(cmds[i].name,arg[0])) { 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n != cmds[i].numargs) { 2303762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("%s requires %d arguments (%d given)\n", 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project cmds[i].name, cmds[i].numargs, n); 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ret = cmds[i].func(arg + 1, reply); 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto done; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2383762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("unsupported command '%s'\n", arg[0]); 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectdone: 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (reply[0]) { 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project n = snprintf(cmd, BUFFER_MAX, "%d", ret); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (n > BUFFER_MAX) n = BUFFER_MAX; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project count = n; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2496215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block// ALOGI("reply: '%s'\n", cmd); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (writex(s, &count, sizeof(count))) return -1; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (writex(s, cmd, count)) return -1; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root/** 25686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root * Initialize all the global variables that are used elsewhere. Returns 0 upon 25786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root * success and -1 on error. 25886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root */ 25986c9584559439504fc57ece2ccd9b6cbd568430cKenny Rootvoid free_globals() { 26086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root size_t i; 26186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 26286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root for (i = 0; i < android_system_dirs.count; i++) { 26386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (android_system_dirs.dirs[i].path != NULL) { 26486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root free(android_system_dirs.dirs[i].path); 26586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 26686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 26786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 26886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root free(android_system_dirs.dirs); 26986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root} 27086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 27186c9584559439504fc57ece2ccd9b6cbd568430cKenny Rootint initialize_globals() { 27286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the android data directory. 27386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (get_path_from_env(&android_data_dir, "ANDROID_DATA") < 0) { 27486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 27586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 27686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 27786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the android app directory. 27886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { 27986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 28086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 28186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 28286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the android protected app directory. 28386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { 28486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 28586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 28686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 2879bbd70a96397bd5f1445ad6c21977fccfb350dfaKenny Root // Get the android app native library directory. 2889bbd70a96397bd5f1445ad6c21977fccfb350dfaKenny Root if (copy_and_append(&android_app_lib_dir, &android_data_dir, APP_LIB_SUBDIR) < 0) { 2899bbd70a96397bd5f1445ad6c21977fccfb350dfaKenny Root return -1; 2909bbd70a96397bd5f1445ad6c21977fccfb350dfaKenny Root } 2919bbd70a96397bd5f1445ad6c21977fccfb350dfaKenny Root 29286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Get the sd-card ASEC mount point. 29386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) { 29486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 29586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 29686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 297197a0c82a1fbf337ec0a85d36b6b89c3d6e8a0acDianne Hackborn // Get the android media directory. 298197a0c82a1fbf337ec0a85d36b6b89c3d6e8a0acDianne Hackborn if (copy_and_append(&android_media_dir, &android_data_dir, MEDIA_SUBDIR) < 0) { 299197a0c82a1fbf337ec0a85d36b6b89c3d6e8a0acDianne Hackborn return -1; 300197a0c82a1fbf337ec0a85d36b6b89c3d6e8a0acDianne Hackborn } 301197a0c82a1fbf337ec0a85d36b6b89c3d6e8a0acDianne Hackborn 30286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // Take note of the system and vendor directories. 30386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root android_system_dirs.count = 2; 30486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 30586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t)); 30686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (android_system_dirs.dirs == NULL) { 3073762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Couldn't allocate array for dirs; aborting\n"); 30886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 30986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 31086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 31186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // system 31286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) { 31386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root free_globals(); 31486c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return -1; 31586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 31686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 3170b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // append "app/" to dirs[0] 3180b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani char *system_app_path = build_string2(android_system_dirs.dirs[0].path, APP_SUBDIR); 3190b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani android_system_dirs.dirs[0].path = system_app_path; 3200b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani android_system_dirs.dirs[0].len = strlen(system_app_path); 3210b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 32286c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // vendor 32386c9584559439504fc57ece2ccd9b6cbd568430cKenny Root // TODO replace this with an environment variable (doesn't exist yet) 3240b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani android_system_dirs.dirs[1].path = "/vendor/app/"; 32586c9584559439504fc57ece2ccd9b6cbd568430cKenny Root android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); 32686c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 32786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root return 0; 32886c9584559439504fc57ece2ccd9b6cbd568430cKenny Root} 32986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 3300b285499db739ba50f2f839d633e763c70e67f96Amith Yamasaniint initialize_directories() { 3315b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey int res = -1; 3325b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 3335b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Read current filesystem layout version to handle upgrade paths 3345b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey char version_path[PATH_MAX]; 3358ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey snprintf(version_path, PATH_MAX, "%s.layout_version", android_data_dir.path); 3368ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey 3378ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey int oldVersion; 3388ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (fs_read_atomic_int(version_path, &oldVersion) == -1) { 3398ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey oldVersion = 0; 3405b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3418ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey int version = oldVersion; 3425b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 3430b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // /data/user 3440b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani char *user_data_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX); 3450b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // /data/data 3460b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani char *legacy_data_dir = build_string2(android_data_dir.path, PRIMARY_USER_PREFIX); 3470b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani // /data/user/0 3485b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey char *primary_data_dir = build_string3(android_data_dir.path, SECONDARY_USER_PREFIX, "0"); 3495b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (!user_data_dir || !legacy_data_dir || !primary_data_dir) { 3505b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 3515b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3525b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 3535b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Make the /data/user directory if necessary 3545b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (access(user_data_dir, R_OK) < 0) { 3555b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (mkdir(user_data_dir, 0711) < 0) { 3565b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 3575b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3585b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) { 3595b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 3605b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3615b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (chmod(user_data_dir, 0711) < 0) { 3625b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 3635b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3645b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3655b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Make the /data/user/0 symlink to /data/data if necessary 3665b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (access(primary_data_dir, R_OK) < 0) { 3675b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (symlink(legacy_data_dir, primary_data_dir)) { 3685b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 3695b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3705b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3715b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 3725b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (version == 0) { 3735b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Introducing multi-user, so migrate /data/media contents into /data/media/0 3748ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey ALOGD("Upgrading /data/media for multi-user"); 3755b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 376dc9b0128c52cc797847240e81ebc6de75229a3abJeff Sharkey // Ensure /data/media 3778ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 378dc9b0128c52cc797847240e81ebc6de75229a3abJeff Sharkey goto fail; 379dc9b0128c52cc797847240e81ebc6de75229a3abJeff Sharkey } 380dc9b0128c52cc797847240e81ebc6de75229a3abJeff Sharkey 3815b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // /data/media.tmp 3825b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey char media_tmp_dir[PATH_MAX]; 3835b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey snprintf(media_tmp_dir, PATH_MAX, "%smedia.tmp", android_data_dir.path); 3845b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 3855b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Only copy when upgrade not already in progress 3865b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (access(media_tmp_dir, F_OK) == -1) { 3875b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (rename(android_media_dir.path, media_tmp_dir) == -1) { 3885b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey ALOGE("Failed to move legacy media path: %s", strerror(errno)); 3895b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 3907ac3ed1d7679e9cb90b44c6ab1629318b17c0690Nick Kralevich } 3910b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 3925b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 3935b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Create /data/media again 3948ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (fs_prepare_dir(android_media_dir.path, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 3955b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 3965b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 3975b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 3988ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey // /data/media/0 3998ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey char owner_media_dir[PATH_MAX]; 4008ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey snprintf(owner_media_dir, PATH_MAX, "%s0", android_media_dir.path); 4018ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey 4025b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Move any owner data into place 4035b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (access(media_tmp_dir, F_OK) == 0) { 4045b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey if (rename(media_tmp_dir, owner_media_dir) == -1) { 4055b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey ALOGE("Failed to move owner media path: %s", strerror(errno)); 4065b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 4075b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 4080b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 40991bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey 41091bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey // Ensure media directories for any existing users 41191bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey DIR *dir; 41291bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey struct dirent *dirent; 41391bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey char user_media_dir[PATH_MAX]; 41491bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey 41591bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey dir = opendir(user_data_dir); 41691bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey if (dir != NULL) { 41791bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey while ((dirent = readdir(dir))) { 41891bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey if (dirent->d_type == DT_DIR) { 41991bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey const char *name = dirent->d_name; 42091bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey 42191bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey // skip "." and ".." 42291bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey if (name[0] == '.') { 42391bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey if (name[1] == 0) continue; 42491bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey if ((name[1] == '.') && (name[2] == 0)) continue; 42591bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey } 42691bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey 42791bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey // /data/media/<user_id> 42891bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey snprintf(user_media_dir, PATH_MAX, "%s%s", android_media_dir.path, name); 4298ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (fs_prepare_dir(user_media_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 43091bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey goto fail; 43191bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey } 43291bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey } 43391bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey } 43491bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey closedir(dir); 43591bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey } 43691bbb8a1e9f8b4324fd086fa9b26a4e9fe57569bJeff Sharkey 4375b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey version = 1; 4380b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 4395b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 4408ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey // /data/media/obb 4418ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey char media_obb_dir[PATH_MAX]; 4428ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey snprintf(media_obb_dir, PATH_MAX, "%sobb", android_media_dir.path); 4438ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey 4448ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (version == 1) { 4458ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey // Introducing /data/media/obb for sharing OBB across users; migrate 4468ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey // any existing OBB files from owner. 4478ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey ALOGD("Upgrading to shared /data/media/obb"); 4488ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey 4498ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey // /data/media/0/Android/obb 4508ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey char owner_obb_path[PATH_MAX]; 4518ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey snprintf(owner_obb_path, PATH_MAX, "%s0/Android/obb", android_media_dir.path); 4528ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey 4538ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey // Only move if target doesn't already exist 4548ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (access(media_obb_dir, F_OK) != 0 && access(owner_obb_path, F_OK) == 0) { 4558ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (rename(owner_obb_path, media_obb_dir) == -1) { 4568ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey ALOGE("Failed to move OBB from owner: %s", strerror(errno)); 4578ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey goto fail; 4588ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey } 4598ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey } 4608ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey 4618ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey version = 2; 4625b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 4635b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 4648ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (ensure_media_user_dirs(0) == -1) { 4658ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey ALOGE("Failed to setup media for user 0"); 4668ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey goto fail; 4678ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey } 4688ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (fs_prepare_dir(media_obb_dir, 0770, AID_MEDIA_RW, AID_MEDIA_RW) == -1) { 4695b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey goto fail; 4705b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey } 4715b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 4728ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey // Persist layout version if changed 4738ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (version != oldVersion) { 4748ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey if (fs_write_atomic_int(version_path, version) == -1) { 4758ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey ALOGE("Failed to save version to %s: %s", version_path, strerror(errno)); 4768ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey goto fail; 4778ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey } 4788ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey } 4798ea0dc6a89b011d4f478c0c8192570d69cf7ce79Jeff Sharkey 4805b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey // Success! 4815b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey res = 0; 4825b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey 4835b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkeyfail: 4845b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey free(user_data_dir); 4855b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey free(legacy_data_dir); 4865b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey free(primary_data_dir); 4875b1ada2562c17921adf6a62ea62bcb445160983cJeff Sharkey return res; 4880b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani} 4890b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 490812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevichstatic void drop_privileges() { 491812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich if (prctl(PR_SET_KEEPCAPS, 1) < 0) { 492812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich ALOGE("prctl(PR_SET_KEEPCAPS) failed: %s\n", strerror(errno)); 493812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich exit(1); 494812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich } 495812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 496812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich if (setgid(AID_INSTALL) < 0) { 497812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich ALOGE("setgid() can't drop privileges; exiting.\n"); 498812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich exit(1); 499812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich } 500812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 501812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich if (setuid(AID_INSTALL) < 0) { 502812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich ALOGE("setuid() can't drop privileges; exiting.\n"); 503812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich exit(1); 504812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich } 505812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 506812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich struct __user_cap_header_struct capheader; 507812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich struct __user_cap_data_struct capdata[2]; 508812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich memset(&capheader, 0, sizeof(capheader)); 509812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich memset(&capdata, 0, sizeof(capdata)); 510812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capheader.version = _LINUX_CAPABILITY_VERSION_3; 511812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capheader.pid = 0; 512812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 513812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted |= CAP_TO_MASK(CAP_DAC_OVERRIDE); 514812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[CAP_TO_INDEX(CAP_CHOWN)].permitted |= CAP_TO_MASK(CAP_CHOWN); 515812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[CAP_TO_INDEX(CAP_SETUID)].permitted |= CAP_TO_MASK(CAP_SETUID); 516812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[CAP_TO_INDEX(CAP_SETGID)].permitted |= CAP_TO_MASK(CAP_SETGID); 517812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 518812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[0].effective = capdata[0].permitted; 519812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[1].effective = capdata[1].permitted; 520812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[0].inheritable = 0; 521812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich capdata[1].inheritable = 0; 522812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 523812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich if (capset(&capheader, &capdata[0]) < 0) { 524812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich ALOGE("capset failed: %s\n", strerror(errno)); 525812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich exit(1); 526812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich } 527812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich} 528812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 52986c9584559439504fc57ece2ccd9b6cbd568430cKenny Rootint main(const int argc, const char *argv[]) { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char buf[BUFFER_MAX]; 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct sockaddr addr; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project socklen_t alen; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int lsocket, s, count; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 535812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich ALOGI("installd firing up\n"); 536812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 53786c9584559439504fc57ece2ccd9b6cbd568430cKenny Root if (initialize_globals() < 0) { 5383762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Could not initialize globals; exiting.\n"); 53986c9584559439504fc57ece2ccd9b6cbd568430cKenny Root exit(1); 54086c9584559439504fc57ece2ccd9b6cbd568430cKenny Root } 54186c9584559439504fc57ece2ccd9b6cbd568430cKenny Root 5420b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani if (initialize_directories() < 0) { 5433762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Could not create directories; exiting.\n"); 5440b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani exit(1); 5450b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani } 5460b285499db739ba50f2f839d633e763c70e67f96Amith Yamasani 547812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich drop_privileges(); 548812b19a425b8304ac9e5408cc8ceb9f363c72559Nick Kralevich 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project lsocket = android_get_control_socket(SOCKET_PATH); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lsocket < 0) { 5513762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exit(1); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listen(lsocket, 5)) { 5553762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Listen on socket failed: %s\n", strerror(errno)); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exit(1); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fcntl(lsocket, F_SETFD, FD_CLOEXEC); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (;;) { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project alen = sizeof(addr); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project s = accept(lsocket, &addr, &alen); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (s < 0) { 5643762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("Accept failed: %s\n", strerror(errno)); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fcntl(s, F_SETFD, FD_CLOEXEC); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5696215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI("new connection\n"); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (;;) { 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned short count; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (readx(s, &count, sizeof(count))) { 5733762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("failed to read size\n"); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((count < 1) || (count >= BUFFER_MAX)) { 5773762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("invalid size %d\n", count); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (readx(s, buf, count)) { 5813762c311729fe9f3af085c14c5c1fb471d994c03Steve Block ALOGE("failed to read command\n"); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project buf[count] = 0; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (execute(s, buf)) break; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5876215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block ALOGI("closing connection\n"); 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project close(s); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return 0; 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 593