From 0545fad98723550607287a86bfee3807c7d26e91 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Mon, 24 Jan 2011 16:42:36 -0800 Subject: dhcpcd: Add Android patches Change-Id: Ia232992f6e18a1494ad12e38c95fd0d2a7520e8e Signed-off-by: Dmitry Shmidt --- config.h | 1 + dhcp.c | 8 ++++++- dhcpcd.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- if-linux.c | 4 ++-- 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/config.h b/config.h index 47c795b..180c63e 100644 --- a/config.h +++ b/config.h @@ -7,6 +7,7 @@ #include "compat/arc4random.h" #include "compat/closefrom.h" #include "compat/strlcpy.h" +#include "compat/getline.h" #ifndef MAX #define MAX(a,b) ((a) >= (b) ? (a) : (b)) diff --git a/dhcp.c b/dhcp.c index bd6c719..0642ba1 100644 --- a/dhcp.c +++ b/dhcp.c @@ -839,7 +839,6 @@ make_message(struct dhcp_message **message, const struct if_options *ifo = iface->state->options; const struct dhcp_lease *lease = &iface->state->lease; - printf("%s: Start\n", __func__); dhcp = xzalloc(sizeof (*dhcp)); m = (uint8_t *)dhcp; p = dhcp->options; @@ -1056,6 +1055,13 @@ write_lease(const struct interface *iface, const struct dhcp_message *dhcp) iface->name, iface->leasefile); fd = open(iface->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444); +#ifdef ANDROID + if (fd == -1 && errno == EACCES) { + /* the lease file might have been created when dhcpcd was running as root */ + unlink(iface->leasefile); + fd = open(iface->leasefile, O_WRONLY | O_CREAT | O_TRUNC, 0444); + } +#endif if (fd == -1) { syslog(LOG_ERR, "%s: open: %m", iface->name); return -1; diff --git a/dhcpcd.c b/dhcpcd.c index 704cbb5..e984ceb 100644 --- a/dhcpcd.c +++ b/dhcpcd.c @@ -70,6 +70,13 @@ const char copyright[] = "Copyright (c) 2006-2010 Roy Marples"; #include "net.h" #include "signals.h" +#ifdef ANDROID +#include +#include +#include +#include +#endif + /* We should define a maximum for the NAK exponential backoff */ #define NAKOFF_MAX 60 @@ -1151,7 +1158,7 @@ start_interface(void *arg) /* Offset lease times and check expiry */ gettimeofday(&now, NULL); if ((time_t)iface->state->lease.leasetime < - now.tv_sec - st.st_mtime) + (time_t)(now.tv_sec - st.st_mtime)) { syslog(LOG_DEBUG, "%s: discarding expired lease", @@ -1702,6 +1709,29 @@ close_sockets(struct interface *iface) } } +#ifdef ANDROID +void switchUser(void) +{ + gid_t groups[] = { 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) { @@ -1711,6 +1741,9 @@ main(int argc, char **argv) pid_t pid; struct timespec ts; +#ifdef ANDROID + switchUser(); +#endif closefrom(3); openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON); setlogmask(LOG_UPTO(LOG_INFO)); @@ -1854,12 +1887,28 @@ main(int argc, char **argv) } } +#ifndef ANDROID + /* android runs us as user "dhcp" */ if (geteuid()) syslog(LOG_WARNING, PACKAGE " will not work correctly unless run as root"); - +#endif if (sig != 0) { +#ifdef ANDROID + char pidpropname[PROPERTY_KEY_MAX]; + char pidpropval[PROPERTY_VALUE_MAX]; + + if (snprintf(pidpropname, + sizeof(pidpropname), + "dhcp.%s.pid", iface->name) >= PROPERTY_KEY_MAX) + exit(EXIT_FAILURE); + property_get(pidpropname, pidpropval, NULL); + if (strlen(pidpropval) == 0) + exit(EXIT_FAILURE); + pid = atoi(pidpropval); +#else pid = read_pid(); +#endif if (pid != 0) syslog(LOG_INFO, "sending signal %d to pid %d", sig, pid); @@ -1891,6 +1940,11 @@ main(int argc, char **argv) } if (!(options & DHCPCD_TEST)) { +#ifdef ANDROID + char pidpropname[PROPERTY_KEY_MAX]; + char pidpropval[PROPERTY_VALUE_MAX]; +#endif +#ifndef ANDROID if ((pid = read_pid()) > 0 && kill(pid, 0) == 0) { @@ -1909,7 +1963,7 @@ main(int argc, char **argv) syslog(LOG_ERR, "mkdir `%s': %m", DBDIR); exit(EXIT_FAILURE); } - +#endif pidfd = open(pidfile, O_WRONLY | O_CREAT | O_NONBLOCK, 0664); if (pidfd == -1) { syslog(LOG_ERR, "open `%s': %m", pidfile); @@ -1923,7 +1977,17 @@ main(int argc, char **argv) } if (set_cloexec(pidfd) == -1) exit(EXIT_FAILURE); +#ifdef ANDROID + if (snprintf(pidpropname, + sizeof(pidpropname), + "dhcp.%s.pid", iface->name) >= PROPERTY_KEY_MAX) + exit(EXIT_FAILURE); + if (snprintf(pidpropval, sizeof(pidpropval), "%d", getpid()) >= PROPERTY_VALUE_MAX) + exit(EXIT_FAILURE); + property_set(pidpropname, pidpropval); +#else writepid(pidfd, getpid()); +#endif } syslog(LOG_INFO, "version " VERSION " starting"); diff --git a/if-linux.c b/if-linux.c index 4a06259..c944a1a 100644 --- a/if-linux.c +++ b/if-linux.c @@ -528,7 +528,7 @@ if_route(const struct interface *iface, if (action == 0) nlm->hdr.nlmsg_flags = NLM_F_REPLACE; else if (action == 1) - nlm->hdr.nlmsg_flags = NLM_F_CREATE | NLM_F_EXCL; + nlm->hdr.nlmsg_flags = NLM_F_CREATE /*| NLM_F_EXCL*/; else nlm->hdr.nlmsg_type = RTM_DELROUTE; nlm->hdr.nlmsg_flags |= NLM_F_REQUEST; @@ -538,7 +538,7 @@ if_route(const struct interface *iface, if (action == -1 || action == -2) nlm->rt.rtm_scope = RT_SCOPE_NOWHERE; else { - nlm->hdr.nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; + nlm->hdr.nlmsg_flags |= NLM_F_CREATE /*| NLM_F_EXCL*/; /* We only change route metrics for kernel routes */ if (destination->s_addr == (iface->addr.s_addr & iface->net.s_addr) && -- cgit v1.1