diff options
author | Niranjan Pendharkar <npendhar@codeaurora.org> | 2011-08-03 17:59:23 -0700 |
---|---|---|
committer | Niranjan Pendharkar <npendhar@codeaurora.org> | 2011-08-03 18:07:01 -0700 |
commit | efb7cd7e24688f6b9e6c98657550f79611025182 (patch) | |
tree | 3832867d94867c77a75e9dc2b0e9c8bfbe82c8e4 | |
parent | f83c01719a3736aebf789d134ba1586d8944580c (diff) | |
download | android_external_connectivity-efb7cd7e24688f6b9e6c98657550f79611025182.tar.gz android_external_connectivity-efb7cd7e24688f6b9e6c98657550f79611025182.tar.bz2 android_external_connectivity-efb7cd7e24688f6b9e6c98657550f79611025182.zip |
cnd: change uid of cnd to radio
cnd starts as uid root but now downgrades itself to uid radio
CRs-fixed: 285706
Change-Id: Ie7de35c42c633bcffa955c295dc8bcf7a196376d
-rw-r--r-- | cnd/src/cnd.c | 1 | ||||
-rwxr-xr-x | cnd/src/cnd_process.cpp | 37 |
2 files changed, 36 insertions, 2 deletions
diff --git a/cnd/src/cnd.c b/cnd/src/cnd.c index 9220ae7..b8783df 100644 --- a/cnd/src/cnd.c +++ b/cnd/src/cnd.c @@ -33,6 +33,7 @@ int main (int argc, char **argv) (strcasecmp(prop_value, "reference") == 0)) { cnd_init(); + cnd_cap_init(); cnd_startEventLoop(); while(1) { diff --git a/cnd/src/cnd_process.cpp b/cnd/src/cnd_process.cpp index 18c1a3d..006c0a4 100755 --- a/cnd/src/cnd_process.cpp +++ b/cnd/src/cnd_process.cpp @@ -29,7 +29,10 @@ #include <binder/Parcel.h> #include <cutils/jstring.h> +#include <linux/capability.h> +#include <linux/prctl.h> #include <sys/types.h> +#include <pwd.h> #include <stdio.h> #include <stdlib.h> @@ -56,6 +59,7 @@ namespace android { #define SOCKET_NAME_CND "cnd" +#define RUN_LEVEL_CND "radio" // match with constant in .java #define MAX_COMMAND_BYTES (8 * 1024) @@ -213,7 +217,7 @@ processCommand (int command, void *data, size_t datalen, CND_Token t) ifName = ((unsigned char **)data)[1]; ipAddr = ((unsigned char **)data)[2]; gatewayAddr = ((unsigned char **)data)[3]; - + CNE_LOGV ("processCommand: iproute2cmd=%d, ipAddr=%s, gatewayAddr=%s, " "ifName=%s", cmd, ipAddr, gatewayAddr, ifName); @@ -1051,7 +1055,7 @@ static void processCommandsCallback(int fd, void *param) } } - CNE_LOGV ("processCommandsCallback: exit loop, ret=%d, errno=%d, fd=%d", + CNE_LOGV ("processCommandsCallback: exit loop, ret=%d, errno=%d, fd=%d", ret, errno, fd); if (ret == 0 || !(errno == EAGAIN || errno == EINTR || errno == EBADF)) { /* fatal error or end-of-stream */ @@ -1226,6 +1230,35 @@ cnd_init (void) } +extern "C" void +cnd_cap_init (void) +{ + __user_cap_header_struct hdr; + __user_cap_data_struct data; + struct passwd* usr_info; + + /* Gather Current Capabilities */ + hdr.version = _LINUX_CAPABILITY_VERSION; + hdr.pid = 0; + if (capget(&hdr, &data) < 0) + CNE_LOGE("cnd_cap_init could not gather current capabilities: %s\n",strerror(errno)); + + /* Tell kernel not clear capabilities when dropping root user id */ + if (prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) + CNE_LOGE("cnd_cap_init could not inform kernel of current capabilities prior to dropping root uid.\n" ); + + /* Drop root uid and change to radio */ + usr_info = getpwnam(RUN_LEVEL_CND); + if (setuid(usr_info->pw_uid) < 0) + CNE_LOGE("cnd_cap_init could not drop root uid."); + + /* Set new process capabilities */ + data.effective = (1 << (CAP_NET_ADMIN))|(1 << (CAP_NET_RAW)); + data.permitted = data.effective; + data.inheritable = 0; + if (capset(&hdr, &data) < 0) + CNE_LOGE("cnd_cap_init could not set capabilities: %s\n",strerror(errno)); +} static void cnd_commandComplete(CND_Token t, CND_Errno e, void *response, size_t responselen) |