#include "uidswap.h"
#include "xmalloc.h"
+#ifdef ANDROID
+#include <private/android_filesystem_config.h>
+#include <linux/capability.h>
+#include <linux/prctl.h>
+#endif
+
/*
* Note: all these functions must work in all of the following cases:
* 1. euid=0, ruid=0
{
uid_t old_uid = getuid();
gid_t old_gid = getgid();
+#ifdef ANDROID
+ struct __user_cap_header_struct header;
+ struct __user_cap_data_struct cap;
+#endif
if (pw == NULL)
fatal("permanently_set_uid: no user given");
debug("permanently_set_uid: %u/%u", (u_int)pw->pw_uid,
(u_int)pw->pw_gid);
+#ifdef ANDROID
+ if (pw->pw_uid == AID_SHELL) {
+ prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
+
+ /* add extra groups needed for shell user:
+ ** AID_LOG to read system logs (adb logcat)
+ ** AID_INPUT to diagnose input issues (getevent)
+ ** AID_INET to diagnose network issues (netcfg, ping)
+ ** AID_GRAPHICS to access the frame buffer
+ ** AID_NET_BT and AID_NET_BT_ADMIN to diagnose bluetooth (hcidump)
+ ** AID_SDCARD_RW to allow writing to the SD card
+ ** AID_MOUNT to allow unmounting the SD card before rebooting
+ ** AID_NET_BW_STATS to read out qtaguid statistics
+ */
+ gid_t groups[] = { AID_LOG, AID_INPUT, AID_INET, AID_GRAPHICS,
+ AID_NET_BT, AID_NET_BT_ADMIN, AID_SDCARD_RW,
+ AID_MOUNT, AID_NET_BW_STATS };
+ setgroups(sizeof(groups)/sizeof(groups[0]), groups);
+ }
+#endif
+
#if defined(HAVE_SETRESGID) && !defined(BROKEN_SETRESGID)
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0)
fatal("setresgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno));
__func__, (u_int)getuid(), (u_int)geteuid(),
(u_int)pw->pw_uid);
}
+
+#ifdef ANDROID
+ if (pw->pw_uid == AID_SHELL) {
+ /* set CAP_SYS_BOOT capability, so "adb reboot" will succeed */
+ header.version = _LINUX_CAPABILITY_VERSION;
+ header.pid = 0;
+ cap.effective = cap.permitted = (1 << CAP_SYS_BOOT);
+ cap.inheritable = 0;
+ capset(&header, &cap);
+ }
+#endif
+
}