int misc_test(int argc, char **argv) { struct phone_encrypt_state ps; if (argc == 1) { misc_get_phone_encrypt_state(&ps); if (ps.state == PHONE_ENCRYPTED) { printf("Phone is encrypted (%x)\n", ps.state); } else { printf("Phone is not encrypted (%x)\n", ps.state); } return 0; } if (atoi(argv[1]) == 0) { ps.state = 0; } else { ps.state = PHONE_ENCRYPTED; } misc_set_phone_encrypt_state(&ps); sync(); return 0; }
/* mount <type> <device> <path> <flags ...> <options> */ int do_mount(int nargs, char **args) { char tmp[64]; char *source, *target, *type; char *options = NULL; unsigned flags = 0; int n, i; int wait = 0; //add for power loss test struct stat stbuf; for (n = 4; n < nargs; n++) { for (i = 0; mount_flags[i].name; i++) { if (!strcmp(args[n], mount_flags[i].name)) { flags |= mount_flags[i].flag; break; } } if (!mount_flags[i].name) { if (!strcmp(args[n], "wait")) wait = 1; /* if our last argument isn't a flag, wolf it up as an option string */ else if (n + 1 == nargs) options = args[n]; } } type = args[1]; source = args[2]; target = args[3]; if (!strncmp(source, "mtd@", 4)) { n = mtd_name_to_number(source + 4); if (n < 0) { return -1; } sprintf(tmp, "/dev/block/mtdblock%d", n); if (wait) wait_for_file(tmp, COMMAND_RETRY_TIMEOUT); if (mount(tmp, target, type, flags, options) < 0) { return -1; } goto exit_success; } else if (!strncmp(source, "loop@", 5)) { int mode, loop, fd; struct loop_info info; mode = (flags & MS_RDONLY) ? O_RDONLY : O_RDWR; fd = open(source + 5, mode); if (fd < 0) { return -1; } for (n = 0; ; n++) { sprintf(tmp, "/dev/block/loop%d", n); loop = open(tmp, mode); if (loop < 0) { return -1; } /* if it is a blank loop device */ if (ioctl(loop, LOOP_GET_STATUS, &info) < 0 && errno == ENXIO) { /* if it becomes our loop device */ if (ioctl(loop, LOOP_SET_FD, fd) >= 0) { close(fd); if (mount(tmp, target, type, flags, options) < 0) { ioctl(loop, LOOP_CLR_FD, 0); close(loop); return -1; } close(loop); goto exit_success; } } close(loop); } close(fd); ERROR("out of loopback devices"); return -1; } else { #ifdef MTK_EMMC_SUPPORT struct phone_encrypt_state ps; if (!strcmp(target, DATA_MNT_POINT)) { if (misc_get_phone_encrypt_state(&ps) < 0) { printf("Failed to get encrypted status in MISC\n"); } else { printf("Success: get encrypted status: 0x%x in MISC\n", ps.state); } } #endif if (wait) wait_for_file(source, COMMAND_RETRY_TIMEOUT); if (mount(source, target, type, flags, options) < 0) { /* If this fails, it may be an encrypted filesystem * or it could just be wiped. If wiped, that will be * handled later in the boot process. * We only support encrypting /data. Check * if we're trying to mount it, and if so, * assume it's encrypted, mount a tmpfs instead. * Then save the orig mount parms in properties * for vold to query when it mounts the real * encrypted /data. */ if (!strcmp(target, DATA_MNT_POINT)) { int fd; if ((fd = open(source, O_RDONLY)) < 0) { printf("Mount /data fail because source(%s) doesn't exist.", source); return -1; } } if (!strcmp(target, DATA_MNT_POINT) && !partition_wiped(source)) { const char *tmpfs_options; tmpfs_options = property_get("ro.crypto.tmpfs_options"); if (mount("tmpfs", target, "tmpfs", MS_NOATIME | MS_NOSUID | MS_NODEV, tmpfs_options) < 0) { return -1; } /* Set the property that triggers the framework to do a minimal * startup and ask the user for a password */ property_set("ro.crypto.state", "encrypted"); property_set("vold.decrypt", "1"); } else { return -1; } } #ifdef MTK_EMMC_SUPPORT else { if (!strcmp(target, DATA_MNT_POINT)) { if (ps.state == PHONE_ENCRYPTED) { ps.state = PHONE_UNCRYPTED; if (misc_set_phone_encrypt_state(&ps) < 0) { printf("Failed to set encrypted status to 0x%x in MISC\n", ps.state); } else { printf("Success: Set encrypted status to 0x%x in MISC\n", ps.state); } } } } #endif if (!strcmp(target, DATA_MNT_POINT)) { char fs_flags[32]; /* Save the original mount options */ property_set("ro.crypto.fs_type", type); property_set("ro.crypto.fs_real_blkdev", source); property_set("ro.crypto.fs_mnt_point", target); if (options) { property_set("ro.crypto.fs_options", options); } snprintf(fs_flags, sizeof(fs_flags), "0x%8.8x", flags); property_set("ro.crypto.fs_flags", fs_flags); } if (!strncmp(type, "ext4", 4)){ if (!strncmp(target, "/data", 5)){ printf("delete lost-found in data dir\n"); system("/system/bin/rm -r /data/lost+found/*"); if (stat("/data/data", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/data file\n"); system("/system/bin/rm -r /data/data"); } if (stat("/data/system", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/system file\n"); system("/system/bin/rm -r /data/system"); } if (stat("/data/misc", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/misc file\n"); system("/system/bin/rm -r /data/misc"); } if (stat("/data/local", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/local file\n"); system("/system/bin/rm -r /data/local"); } if (stat("/data/app-private", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/app-private file\n"); system("/system/bin/rm -r /data/app-private"); } if (stat("/data/dalvik-cache", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/dalvik-cache file\n"); system("/system/bin/rm -r /data/dalvik-cache"); } if (stat("/data/property", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/property file\n"); system("/system/bin/rm -r /data/property"); } if (stat("/data/mvg_root", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/mvg_root file\n"); system("/system/bin/rm -r /data/mvg_root"); } if (stat("/data/anr", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/anr file\n"); system("/system/bin/rm -r /data/anr"); } if (stat("/data/app", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/app file\n"); system("/system/bin/rm -r /data/app"); } if (stat("/data/nvram", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/nvram file\n"); system("/system/bin/rm -r /data/nvram"); } if (stat("/data/secure", &stbuf) < 0){ printf("stat syscall fail\n"); } if (S_ISREG(stbuf.st_mode)){ printf("delete /data/secure file\n"); system("/system/bin/rm -r /data/secure"); } } if (!strncmp(target, "/cache", 6)){ printf("delete lost-found in cache dir\n"); system("/system/bin/rm -r /cache/lost+found/*"); } } } exit_success: /* If not running encrypted, then set the property saying we are * unencrypted, and also trigger the action for a nonencrypted system. */ if (!strcmp(target, DATA_MNT_POINT)) { const char *prop; prop = property_get("ro.crypto.state"); if (! prop) { prop = "notset"; } if (strcmp(prop, "encrypted")) { property_set("ro.crypto.state", "unencrypted"); action_for_each_trigger("nonencrypted", action_add_queue_tail); } } return 0; }