diff options
Diffstat (limited to 'init')
| -rw-r--r-- | init/builtins.c | 42 | ||||
| -rw-r--r-- | init/devices.c | 2 | ||||
| -rw-r--r-- | init/property_service.c | 26 |
3 files changed, 58 insertions, 12 deletions
diff --git a/init/builtins.c b/init/builtins.c index c474198..6032184 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -473,6 +473,26 @@ exit_success: } +static int wipe_data_via_recovery() +{ + mkdir("/cache/recovery", 0700); + int fd = open("/cache/recovery/command", O_RDWR|O_CREAT|O_TRUNC, 0600); + if (fd >= 0) { + write(fd, "--wipe_data", strlen("--wipe_data") + 1); + close(fd); + } else { + ERROR("could not open /cache/recovery/command\n"); + return -1; + } + android_reboot(ANDROID_RB_RESTART2, 0, "recovery"); + while (1) { pause(); } // never reached +} + + +/* + * This function might request a reboot, in which case it will + * not return. + */ int do_mount_all(int nargs, char **args) { pid_t pid; @@ -510,23 +530,33 @@ int do_mount_all(int nargs, char **args) if (child_ret == -1) { ERROR("fs_mgr_mount_all returned an error\n"); } - exit(child_ret); + _exit(child_ret); } else { /* fork failed, return an error */ return -1; } - /* ret is 1 if the device is encrypted, 0 if not, and -1 on error */ - if (ret == 1) { + if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) { + property_set("ro.crypto.state", "unencrypted"); + property_set("vold.decrypt", "trigger_encryption"); + } else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) { property_set("ro.crypto.state", "encrypted"); - property_set("vold.decrypt", "1"); - } else if (ret == 0) { + property_set("vold.decrypt", "trigger_default_encryption"); + } else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) { property_set("ro.crypto.state", "unencrypted"); /* If fs_mgr determined this is an unencrypted device, then trigger * that action. */ action_for_each_trigger("nonencrypted", action_add_queue_tail); - } + } else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) { + /* Setup a wipe via recovery, and reboot into recovery */ + ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n"); + ret = wipe_data_via_recovery(); + /* If reboot worked, there is no return. */ + } else if (ret > 0) { + ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret); + } + /* else ... < 0: error */ return ret; } diff --git a/init/devices.c b/init/devices.c index e27c311..1012fee 100644 --- a/init/devices.c +++ b/init/devices.c @@ -942,7 +942,7 @@ static void handle_firmware_event(struct uevent *uevent) } } -#define UEVENT_MSG_LEN 1024 +#define UEVENT_MSG_LEN 2048 void handle_device_fd() { char msg[UEVENT_MSG_LEN+2]; diff --git a/init/property_service.c b/init/property_service.c index d112699..1902b77 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -24,6 +24,7 @@ #include <dirent.h> #include <limits.h> #include <errno.h> +#include <sys/poll.h> #include <cutils/misc.h> #include <cutils/sockets.h> @@ -181,7 +182,6 @@ static void write_persistent_property(const char *name, const char *value) static bool is_legal_property_name(const char* name, size_t namelen) { size_t i; - bool previous_was_dot = false; if (namelen >= PROP_NAME_MAX) return false; if (namelen < 1) return false; if (name[0] == '.') return false; @@ -191,11 +191,10 @@ static bool is_legal_property_name(const char* name, size_t namelen) /* Don't allow ".." to appear in a property name */ for (i = 0; i < namelen; i++) { if (name[i] == '.') { - if (previous_was_dot == true) return false; - previous_was_dot = true; + // i=0 is guaranteed to never have a dot. See above. + if (name[i-1] == '.') return false; continue; } - previous_was_dot = false; if (name[i] == '_' || name[i] == '-') continue; if (name[i] >= 'a' && name[i] <= 'z') continue; if (name[i] >= 'A' && name[i] <= 'Z') continue; @@ -268,6 +267,9 @@ void handle_property_set_fd() socklen_t addr_size = sizeof(addr); socklen_t cr_size = sizeof(cr); char * source_ctx = NULL; + struct pollfd ufds[1]; + const int timeout_ms = 2 * 1000; /* Default 2 sec timeout for caller to send property. */ + int nr; if ((s = accept(property_set_fd, (struct sockaddr *) &addr, &addr_size)) < 0) { return; @@ -280,7 +282,21 @@ void handle_property_set_fd() return; } - r = TEMP_FAILURE_RETRY(recv(s, &msg, sizeof(msg), 0)); + ufds[0].fd = s; + ufds[0].events = POLLIN; + ufds[0].revents = 0; + nr = TEMP_FAILURE_RETRY(poll(ufds, 1, timeout_ms)); + if (nr == 0) { + ERROR("sys_prop: timeout waiting for uid=%d to send property message.\n", cr.uid); + close(s); + return; + } else if (nr < 0) { + ERROR("sys_prop: error waiting for uid=%d to send property message. err=%d %s\n", cr.uid, errno, strerror(errno)); + close(s); + return; + } + + r = TEMP_FAILURE_RETRY(recv(s, &msg, sizeof(msg), MSG_DONTWAIT)); if(r != sizeof(prop_msg)) { ERROR("sys_prop: mis-match msg size received: %d expected: %zu errno: %d\n", r, sizeof(prop_msg), errno); |
