1 /* 2 ** Copyright 2008, The Android Open Source Project 3 ** 4 ** Licensed under the Apache License, Version 2.0 (the "License"); 5 ** you may not use this file except in compliance with the License. 6 ** You may obtain a copy of the License at 7 ** 8 ** http://www.apache.org/licenses/LICENSE-2.0 9 ** 10 ** Unless required by applicable law or agreed to in writing, software 11 ** distributed under the License is distributed on an "AS IS" BASIS, 12 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 ** See the License for the specific language governing permissions and 14 ** limitations under the License. 15 */ 16 17 #include "installd.h" 18 19 20 #define BUFFER_MAX 1024 /* input buffer for commands */ 21 #define TOKEN_MAX 8 /* max number of arguments in buffer */ 22 #define REPLY_MAX 256 /* largest reply allowed */ 23 24 static int do_ping(char **arg, char reply[REPLY_MAX]) 25 { 26 return 0; 27 } 28 29 static int do_install(char **arg, char reply[REPLY_MAX]) 30 { 31 return install(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */ 32 } 33 34 static int do_dexopt(char **arg, char reply[REPLY_MAX]) 35 { 36 /* apk_path, uid, is_public */ 37 return dexopt(arg[0], atoi(arg[1]), atoi(arg[2])); 38 } 39 40 static int do_move_dex(char **arg, char reply[REPLY_MAX]) 41 { 42 return move_dex(arg[0], arg[1]); /* src, dst */ 43 } 44 45 static int do_rm_dex(char **arg, char reply[REPLY_MAX]) 46 { 47 return rm_dex(arg[0]); /* pkgname */ 48 } 49 50 static int do_remove(char **arg, char reply[REPLY_MAX]) 51 { 52 return uninstall(arg[0], atoi(arg[1])); /* pkgname, userid */ 53 } 54 55 static int do_rename(char **arg, char reply[REPLY_MAX]) 56 { 57 return renamepkg(arg[0], arg[1]); /* oldpkgname, newpkgname */ 58 } 59 60 static int do_free_cache(char **arg, char reply[REPLY_MAX]) /* TODO int:free_size */ 61 { 62 return free_cache((int64_t)atoll(arg[0])); /* free_size */ 63 } 64 65 static int do_rm_cache(char **arg, char reply[REPLY_MAX]) 66 { 67 return delete_cache(arg[0]); /* pkgname */ 68 } 69 70 static int do_protect(char **arg, char reply[REPLY_MAX]) 71 { 72 return protect(arg[0], atoi(arg[1])); /* pkgname, gid */ 73 } 74 75 static int do_get_size(char **arg, char reply[REPLY_MAX]) 76 { 77 int64_t codesize = 0; 78 int64_t datasize = 0; 79 int64_t cachesize = 0; 80 int64_t asecsize = 0; 81 int res = 0; 82 83 /* pkgdir, apkpath */ 84 res = get_size(arg[0], arg[1], arg[2], arg[3], &codesize, &datasize, &cachesize, &asecsize); 85 86 /* 87 * Each int64_t can take up 22 characters printed out. Make sure it 88 * doesn't go over REPLY_MAX in the future. 89 */ 90 snprintf(reply, REPLY_MAX, "%" PRId64 " %" PRId64 " %" PRId64 " %" PRId64, 91 codesize, datasize, cachesize, asecsize); 92 return res; 93 } 94 95 static int do_rm_user_data(char **arg, char reply[REPLY_MAX]) 96 { 97 return delete_user_data(arg[0], atoi(arg[1])); /* pkgname, userid */ 98 } 99 100 static int do_mk_user_data(char **arg, char reply[REPLY_MAX]) 101 { 102 return make_user_data(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, userid */ 103 } 104 105 static int do_rm_user(char **arg, char reply[REPLY_MAX]) 106 { 107 return delete_persona(atoi(arg[0])); /* userid */ 108 } 109 110 static int do_movefiles(char **arg, char reply[REPLY_MAX]) 111 { 112 return movefiles(); 113 } 114 115 static int do_linklib(char **arg, char reply[REPLY_MAX]) 116 { 117 return linklib(arg[0], arg[1]); 118 } 119 120 static int do_unlinklib(char **arg, char reply[REPLY_MAX]) 121 { 122 return unlinklib(arg[0]); 123 } 124 125 struct cmdinfo { 126 const char *name; 127 unsigned numargs; 128 int (*func)(char **arg, char reply[REPLY_MAX]); 129 }; 130 131 struct cmdinfo cmds[] = { 132 { "ping", 0, do_ping }, 133 { "install", 3, do_install }, 134 { "dexopt", 3, do_dexopt }, 135 { "movedex", 2, do_move_dex }, 136 { "rmdex", 1, do_rm_dex }, 137 { "remove", 2, do_remove }, 138 { "rename", 2, do_rename }, 139 { "freecache", 1, do_free_cache }, 140 { "rmcache", 1, do_rm_cache }, 141 { "protect", 2, do_protect }, 142 { "getsize", 4, do_get_size }, 143 { "rmuserdata", 2, do_rm_user_data }, 144 { "movefiles", 0, do_movefiles }, 145 { "linklib", 2, do_linklib }, 146 { "unlinklib", 1, do_unlinklib }, 147 { "mkuserdata", 3, do_mk_user_data }, 148 { "rmuser", 1, do_rm_user }, 149 }; 150 151 static int readx(int s, void *_buf, int count) 152 { 153 char *buf = _buf; 154 int n = 0, r; 155 if (count < 0) return -1; 156 while (n < count) { 157 r = read(s, buf + n, count - n); 158 if (r < 0) { 159 if (errno == EINTR) continue; 160 LOGE("read error: %s\n", strerror(errno)); 161 return -1; 162 } 163 if (r == 0) { 164 LOGE("eof\n"); 165 return -1; /* EOF */ 166 } 167 n += r; 168 } 169 return 0; 170 } 171 172 static int writex(int s, const void *_buf, int count) 173 { 174 const char *buf = _buf; 175 int n = 0, r; 176 if (count < 0) return -1; 177 while (n < count) { 178 r = write(s, buf + n, count - n); 179 if (r < 0) { 180 if (errno == EINTR) continue; 181 LOGE("write error: %s\n", strerror(errno)); 182 return -1; 183 } 184 n += r; 185 } 186 return 0; 187 } 188 189 190 /* Tokenize the command buffer, locate a matching command, 191 * ensure that the required number of arguments are provided, 192 * call the function(), return the result. 193 */ 194 static int execute(int s, char cmd[BUFFER_MAX]) 195 { 196 char reply[REPLY_MAX]; 197 char *arg[TOKEN_MAX+1]; 198 unsigned i; 199 unsigned n = 0; 200 unsigned short count; 201 int ret = -1; 202 203 // LOGI("execute('%s')\n", cmd); 204 205 /* default reply is "" */ 206 reply[0] = 0; 207 208 /* n is number of args (not counting arg[0]) */ 209 arg[0] = cmd; 210 while (*cmd) { 211 if (isspace(*cmd)) { 212 *cmd++ = 0; 213 n++; 214 arg[n] = cmd; 215 if (n == TOKEN_MAX) { 216 LOGE("too many arguments\n"); 217 goto done; 218 } 219 } 220 cmd++; 221 } 222 223 for (i = 0; i < sizeof(cmds) / sizeof(cmds[0]); i++) { 224 if (!strcmp(cmds[i].name,arg[0])) { 225 if (n != cmds[i].numargs) { 226 LOGE("%s requires %d arguments (%d given)\n", 227 cmds[i].name, cmds[i].numargs, n); 228 } else { 229 ret = cmds[i].func(arg + 1, reply); 230 } 231 goto done; 232 } 233 } 234 LOGE("unsupported command '%s'\n", arg[0]); 235 236 done: 237 if (reply[0]) { 238 n = snprintf(cmd, BUFFER_MAX, "%d %s", ret, reply); 239 } else { 240 n = snprintf(cmd, BUFFER_MAX, "%d", ret); 241 } 242 if (n > BUFFER_MAX) n = BUFFER_MAX; 243 count = n; 244 245 // LOGI("reply: '%s'\n", cmd); 246 if (writex(s, &count, sizeof(count))) return -1; 247 if (writex(s, cmd, count)) return -1; 248 return 0; 249 } 250 251 /** 252 * Initialize all the global variables that are used elsewhere. Returns 0 upon 253 * success and -1 on error. 254 */ 255 void free_globals() { 256 size_t i; 257 258 for (i = 0; i < android_system_dirs.count; i++) { 259 if (android_system_dirs.dirs[i].path != NULL) { 260 free(android_system_dirs.dirs[i].path); 261 } 262 } 263 264 free(android_system_dirs.dirs); 265 } 266 267 int initialize_globals() { 268 // Get the android data directory. 269 if (get_path_from_env(&android_data_dir, "ANDROID_DATA") < 0) { 270 return -1; 271 } 272 273 // Get the android app directory. 274 if (copy_and_append(&android_app_dir, &android_data_dir, APP_SUBDIR) < 0) { 275 return -1; 276 } 277 278 // Get the android protected app directory. 279 if (copy_and_append(&android_app_private_dir, &android_data_dir, PRIVATE_APP_SUBDIR) < 0) { 280 return -1; 281 } 282 283 // Get the sd-card ASEC mount point. 284 if (get_path_from_env(&android_asec_dir, "ASEC_MOUNTPOINT") < 0) { 285 return -1; 286 } 287 288 // Take note of the system and vendor directories. 289 android_system_dirs.count = 2; 290 291 android_system_dirs.dirs = calloc(android_system_dirs.count, sizeof(dir_rec_t)); 292 if (android_system_dirs.dirs == NULL) { 293 LOGE("Couldn't allocate array for dirs; aborting\n"); 294 return -1; 295 } 296 297 // system 298 if (get_path_from_env(&android_system_dirs.dirs[0], "ANDROID_ROOT") < 0) { 299 free_globals(); 300 return -1; 301 } 302 303 // append "app/" to dirs[0] 304 char *system_app_path = build_string2(android_system_dirs.dirs[0].path, APP_SUBDIR); 305 android_system_dirs.dirs[0].path = system_app_path; 306 android_system_dirs.dirs[0].len = strlen(system_app_path); 307 308 // vendor 309 // TODO replace this with an environment variable (doesn't exist yet) 310 android_system_dirs.dirs[1].path = "/vendor/app/"; 311 android_system_dirs.dirs[1].len = strlen(android_system_dirs.dirs[1].path); 312 313 return 0; 314 } 315 316 int initialize_directories() { 317 // /data/user 318 char *user_data_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX); 319 // /data/data 320 char *legacy_data_dir = build_string2(android_data_dir.path, PRIMARY_USER_PREFIX); 321 // /data/user/0 322 char *primary_data_dir = build_string3(android_data_dir.path, SECONDARY_USER_PREFIX, 323 "0"); 324 int ret = -1; 325 if (user_data_dir != NULL && primary_data_dir != NULL && legacy_data_dir != NULL) { 326 ret = 0; 327 // Make the /data/user directory if necessary 328 if (access(user_data_dir, R_OK) < 0) { 329 if (mkdir(user_data_dir, 0755) < 0) { 330 return -1; 331 } 332 if (chown(user_data_dir, AID_SYSTEM, AID_SYSTEM) < 0) { 333 return -1; 334 } 335 } 336 // Make the /data/user/0 symlink to /data/data if necessary 337 if (access(primary_data_dir, R_OK) < 0) { 338 ret = symlink(legacy_data_dir, primary_data_dir); 339 } 340 free(user_data_dir); 341 free(legacy_data_dir); 342 free(primary_data_dir); 343 } 344 return ret; 345 } 346 347 int main(const int argc, const char *argv[]) { 348 char buf[BUFFER_MAX]; 349 struct sockaddr addr; 350 socklen_t alen; 351 int lsocket, s, count; 352 353 if (initialize_globals() < 0) { 354 LOGE("Could not initialize globals; exiting.\n"); 355 exit(1); 356 } 357 358 if (initialize_directories() < 0) { 359 LOGE("Could not create directories; exiting.\n"); 360 exit(1); 361 } 362 363 lsocket = android_get_control_socket(SOCKET_PATH); 364 if (lsocket < 0) { 365 LOGE("Failed to get socket from environment: %s\n", strerror(errno)); 366 exit(1); 367 } 368 if (listen(lsocket, 5)) { 369 LOGE("Listen on socket failed: %s\n", strerror(errno)); 370 exit(1); 371 } 372 fcntl(lsocket, F_SETFD, FD_CLOEXEC); 373 374 for (;;) { 375 alen = sizeof(addr); 376 s = accept(lsocket, &addr, &alen); 377 if (s < 0) { 378 LOGE("Accept failed: %s\n", strerror(errno)); 379 continue; 380 } 381 fcntl(s, F_SETFD, FD_CLOEXEC); 382 383 LOGI("new connection\n"); 384 for (;;) { 385 unsigned short count; 386 if (readx(s, &count, sizeof(count))) { 387 LOGE("failed to read size\n"); 388 break; 389 } 390 if ((count < 1) || (count >= BUFFER_MAX)) { 391 LOGE("invalid size %d\n", count); 392 break; 393 } 394 if (readx(s, buf, count)) { 395 LOGE("failed to read command\n"); 396 break; 397 } 398 buf[count] = 0; 399 if (execute(s, buf)) break; 400 } 401 LOGI("closing connection\n"); 402 close(s); 403 } 404 405 return 0; 406 } 407