From ab3df62f7b5584af6dee4f5ec069b70dd4f4cee6 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Wed, 19 Jun 2013 17:20:24 -0700 Subject: [PATCH] netd: reduce privileges netd doesn't need full root capabilities. Rather, it only needs CAP_NET_ADMIN and CAP_NET_RAW. Reduce the capabilities to that set. netd continues to run with UID=0, which allows applications spawned by netd to continue to have CAP_NET_ADMIN and CAP_NET_RAW. It also allows netd to access /proc and /sys files as UID=0. Change-Id: I439d22150109697213c0cc83276ddb668007b978 --- main.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/main.cpp b/main.cpp index b466e42..e86a58b 100644 --- a/main.cpp +++ b/main.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include @@ -39,6 +41,42 @@ static void coldboot(const char *path); static void sigchld_handler(int sig); static void blockSigpipe(); +static void dropPrivileges() { + struct __user_cap_header_struct header; + struct __user_cap_data_struct cap[2]; + int i; + int result; + + // First drop unneeded capabilities from our bounding set, + // which affects children we exec. + for (i = 0; prctl(PR_CAPBSET_READ, i, 0, 0, 0) >= 0; i++) { + if (i == CAP_NET_ADMIN || i == CAP_NET_RAW) { + continue; + } + result = prctl(PR_CAPBSET_DROP, i, 0, 0, 0); + if (result != 0) { + perror("PR_CAPBSET_DROP failed: unable to drop privileges"); + exit(1); + } + } + + // Then drop capabilities from the current process. + memset(&header, 0, sizeof(header)); + memset(cap, 0, sizeof(cap)); + + header.version = _LINUX_CAPABILITY_VERSION_3; + header.pid = 0; + cap[CAP_TO_INDEX(CAP_NET_ADMIN)].effective |= CAP_TO_MASK(CAP_NET_ADMIN); + cap[CAP_TO_INDEX(CAP_NET_ADMIN)].permitted |= CAP_TO_MASK(CAP_NET_ADMIN); + cap[CAP_TO_INDEX(CAP_NET_RAW)].effective |= CAP_TO_MASK(CAP_NET_RAW); + cap[CAP_TO_INDEX(CAP_NET_RAW)].permitted |= CAP_TO_MASK(CAP_NET_RAW); + result = capset(&header, cap); + if (result != 0) { + perror("capset failed: unable to drop privileges"); + exit(1); + } +} + int main() { CommandListener *cl; @@ -47,6 +85,7 @@ int main() { MDnsSdListener *mdnsl; ALOGI("Netd 1.0 starting"); + dropPrivileges(); // signal(SIGCHLD, sigchld_handler); blockSigpipe(); -- 2.11.0