aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJorge Lucangeli Obes <jorgelo@google.com>2015-09-30 18:08:47 -0700
committerSamuel Tan <samueltan@google.com>2015-10-01 09:52:53 -0700
commite0b0b41fe04d8189ecea8045464b4870b7ce4e23 (patch)
treeee36ee06307b58f4b0b510c29d6da5597403e887
parent14596ac959f09d8824dc2ee9a3b20ad7fe3de068 (diff)
downloaddhcpcd-6.8.2-e0b0b41fe04d8189ecea8045464b4870b7ce4e23.tar.gz
dhcpcd-6.8.2: switch user after starting dhcpcd-6.8.2
Have dhcpcd-6.8.2 switch itself to the dhcp uid and gid after spawning. This assumes that dhcpcd-6.8.2 is started as root, which is current the case when shill spawns it. BUG: 24408645 TEST: dhcpcd-6.8.2 builds and is started successfully by shill. Change-Id: Ia14c31ddd7ac06cc19f0541ae3c7bf0f019447ce
-rw-r--r--dhcpcd.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/dhcpcd.c b/dhcpcd.c
index b36cdc7..e0908cf 100644
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -49,6 +49,12 @@ const char dhcpcd_copyright[] = "Copyright (c) 2006-2015 Roy Marples";
#include <unistd.h>
#include <time.h>
+#if defined(__ANDROID__)
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#include <private/android_filesystem_config.h>
+#endif /* __ANDROID__ */
+
#include "config.h"
#include "arp.h"
#include "common.h"
@@ -1398,6 +1404,30 @@ dhcpcd_handleargs(struct dhcpcd_ctx *ctx, struct fd_list *fd,
return 0;
}
+#if defined(__ANDROID__)
+static void
+switch_user(void)
+{
+ gid_t groups[] = { AID_DBUS, AID_INET, AID_SHELL };
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+
+ setgroups(sizeof(groups)/sizeof(groups[0]), groups);
+
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+ setgid(AID_DHCP);
+ setuid(AID_DHCP);
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+ cap.effective = cap.permitted =
+ (1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW) |
+ (1 << CAP_NET_BROADCAST) | (1 << CAP_NET_BIND_SERVICE);
+ cap.inheritable = 0;
+ capset(&header, &cap);
+}
+#endif /* __ANDROID__ */
+
int
main(int argc, char **argv)
{
@@ -1417,6 +1447,10 @@ main(int argc, char **argv)
#endif
char ifn[IF_NAMESIZE];
+#if defined(__ANDROID__)
+ switch_user();
+#endif // __ANDROID__
+
/* Test for --help and --version */
if (argc > 1) {
if (strcmp(argv[1], "--help") == 0) {
@@ -1746,11 +1780,15 @@ main(int argc, char **argv)
goto exit_failure;
}
- /* Ensure we have the needed directories */
+#if !defined(__ANDROID__)
+ /* Ensure we have the needed directories
+ * On Android, we assume that these directories have been created
+ * by calls to mkdir in an init.rc file. */
if (mkdir(RUNDIR, 0755) == -1 && errno != EEXIST)
logger(&ctx, LOG_ERR, "mkdir `%s': %m", RUNDIR);
if (mkdir(DBDIR, 0755) == -1 && errno != EEXIST)
logger(&ctx, LOG_ERR, "mkdir `%s': %m", DBDIR);
+#endif /* __ANDROID__ */
opt = O_WRONLY | O_CREAT | O_NONBLOCK;
#ifdef O_CLOEXEC