From 4515d81e7e9d4b11dfdb29493f55e3ef548fbbe8 Mon Sep 17 00:00:00 2001 From: JP Abgrall <jpa@google.com> Date: Fri, 31 Jan 2014 14:37:07 -0800 Subject: init: prevent waiting forever when a setprop is incomplete. Any app can socket_local_client_connect(s, "property_service", ANDROID_SOCKET_NAMESPACE_RESERVED, SOCK_STREAM) and just keep it open without sending anything. From then on, the property_service.c::handle_property_set_fd() will just recv() forever. This prevents any other properties (i.e. property_set("sys.powerctl", "reboot")) from being processed. Now, we just poll() for 2 sec before recv(...,MSG_DONTWAIT). Bug: 12061560 Change-Id: Iffea4ebb444c7100b59c43ed87aecc5c99f9d3e8 --- init/property_service.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'init') diff --git a/init/property_service.c b/init/property_service.c index ac63377..ff22677 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> @@ -368,6 +369,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; @@ -380,7 +384,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); @@ -522,7 +540,7 @@ static void load_persistent_properties() || (sb.st_uid != 0) || (sb.st_gid != 0) || (sb.st_nlink != 1)) { - ERROR("skipping insecure property file %s (uid=%u gid=%u nlink=%d mode=%o)\n", + ERROR("skipping insecure property file %s (uid=%lu gid=%lu nlink=%d mode=%o)\n", entry->d_name, sb.st_uid, sb.st_gid, sb.st_nlink, sb.st_mode); close(fd); continue; -- cgit v1.1