summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2014-01-31 14:37:07 -0800
committerJP Abgrall <jpa@google.com>2014-01-31 14:53:21 -0800
commit4515d81e7e9d4b11dfdb29493f55e3ef548fbbe8 (patch)
treed3c00c58b9c7c90408d3289d72d3ac452829d821 /init
parent480fdd524da3aa24429e46b81f52651f95c1c59a (diff)
downloadsystem_core-4515d81e7e9d4b11dfdb29493f55e3ef548fbbe8.zip
system_core-4515d81e7e9d4b11dfdb29493f55e3ef548fbbe8.tar.gz
system_core-4515d81e7e9d4b11dfdb29493f55e3ef548fbbe8.tar.bz2
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
Diffstat (limited to 'init')
-rw-r--r--init/property_service.c22
1 files changed, 20 insertions, 2 deletions
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;