Merge changes 23694,23695,23696 into eclair
* changes: init.rc: Add dumpstate service init: Add support for enforcing setprop by caller's group. adb: "adb bugreport" now runs dumpstate via init rather than execing it in the shell.
This commit is contained in:
commit
e991decf34
4 changed files with 81 additions and 40 deletions
|
|
@ -929,7 +929,7 @@ top:
|
||||||
|
|
||||||
if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
|
if(!strcmp(argv[0], "remount") || !strcmp(argv[0], "reboot")
|
||||||
|| !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
|
|| !strcmp(argv[0], "tcpip") || !strcmp(argv[0], "usb")
|
||||||
|| !strcmp(argv[0], "root")) {
|
|| !strcmp(argv[0], "root") || !strcmp(argv[0], "bugreport")) {
|
||||||
char command[100];
|
char command[100];
|
||||||
if (argc > 1)
|
if (argc > 1)
|
||||||
snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
|
snprintf(command, sizeof(command), "%s:%s", argv[0], argv[1]);
|
||||||
|
|
@ -945,14 +945,6 @@ top:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!strcmp(argv[0], "bugreport")) {
|
|
||||||
if (argc != 1) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
do_cmd(ttype, serial, "shell", "dumpstate", "-", 0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* adb_command() wrapper commands */
|
/* adb_command() wrapper commands */
|
||||||
|
|
||||||
if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
|
if(!strncmp(argv[0], "wait-for-", strlen("wait-for-"))) {
|
||||||
|
|
|
||||||
|
|
@ -188,6 +188,43 @@ void reboot_service(int fd, void *arg)
|
||||||
adb_close(fd);
|
adb_close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void bugreport_service(int fd, void *cookie)
|
||||||
|
{
|
||||||
|
char buffer[MAX_PAYLOAD];
|
||||||
|
int i, s;
|
||||||
|
|
||||||
|
/* start the dumpstate service */
|
||||||
|
property_set("ctl.start", "dumpstate");
|
||||||
|
|
||||||
|
/* socket will not be available until service starts */
|
||||||
|
for (i = 0; i < 10; i++) {
|
||||||
|
s = socket_local_client("dumpstate",
|
||||||
|
ANDROID_SOCKET_NAMESPACE_RESERVED,
|
||||||
|
SOCK_STREAM);
|
||||||
|
if (s >= 0)
|
||||||
|
break;
|
||||||
|
/* try again in 1 second */
|
||||||
|
sleep(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s < 0) {
|
||||||
|
const char* failed = "Failed to connect to dumpstate service\n";
|
||||||
|
writex(fd, failed, strlen(failed));
|
||||||
|
adb_close(fd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int length = adb_read(s, buffer, sizeof(buffer));
|
||||||
|
if (length <= 0)
|
||||||
|
break;
|
||||||
|
if (adb_write(fd, buffer, length) <= 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
adb_close(s);
|
||||||
|
adb_close(fd);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -469,6 +506,8 @@ int service_to_fd(const char *name)
|
||||||
ret = create_service_thread(restart_tcp_service, (void *)port);
|
ret = create_service_thread(restart_tcp_service, (void *)port);
|
||||||
} else if(!strncmp(name, "usb:", 4)) {
|
} else if(!strncmp(name, "usb:", 4)) {
|
||||||
ret = create_service_thread(restart_usb_service, NULL);
|
ret = create_service_thread(restart_usb_service, NULL);
|
||||||
|
} else if(!strncmp(name, "bugreport:", 10)) {
|
||||||
|
ret = create_service_thread(bugreport_service, NULL);
|
||||||
#endif
|
#endif
|
||||||
#if 0
|
#if 0
|
||||||
} else if(!strncmp(name, "echo:", 5)){
|
} else if(!strncmp(name, "echo:", 5)){
|
||||||
|
|
|
||||||
|
|
@ -52,31 +52,32 @@ static int persistent_properties_loaded = 0;
|
||||||
struct {
|
struct {
|
||||||
const char *prefix;
|
const char *prefix;
|
||||||
unsigned int uid;
|
unsigned int uid;
|
||||||
|
unsigned int gid;
|
||||||
} property_perms[] = {
|
} property_perms[] = {
|
||||||
{ "net.rmnet0.", AID_RADIO },
|
{ "net.rmnet0.", AID_RADIO, 0 },
|
||||||
{ "net.gprs.", AID_RADIO },
|
{ "net.gprs.", AID_RADIO, 0 },
|
||||||
{ "net.ppp", AID_RADIO },
|
{ "net.ppp", AID_RADIO, 0 },
|
||||||
{ "ril.", AID_RADIO },
|
{ "ril.", AID_RADIO, 0 },
|
||||||
{ "gsm.", AID_RADIO },
|
{ "gsm.", AID_RADIO, 0 },
|
||||||
{ "persist.radio", AID_RADIO },
|
{ "persist.radio", AID_RADIO, 0 },
|
||||||
{ "net.dns", AID_RADIO },
|
{ "net.dns", AID_RADIO, 0 },
|
||||||
{ "net.", AID_SYSTEM },
|
{ "net.", AID_SYSTEM, 0 },
|
||||||
{ "dev.", AID_SYSTEM },
|
{ "dev.", AID_SYSTEM, 0 },
|
||||||
{ "runtime.", AID_SYSTEM },
|
{ "runtime.", AID_SYSTEM, 0 },
|
||||||
{ "hw.", AID_SYSTEM },
|
{ "hw.", AID_SYSTEM, 0 },
|
||||||
{ "sys.", AID_SYSTEM },
|
{ "sys.", AID_SYSTEM, 0 },
|
||||||
{ "service.", AID_SYSTEM },
|
{ "service.", AID_SYSTEM, 0 },
|
||||||
{ "wlan.", AID_SYSTEM },
|
{ "wlan.", AID_SYSTEM, 0 },
|
||||||
{ "dhcp.", AID_SYSTEM },
|
{ "dhcp.", AID_SYSTEM, 0 },
|
||||||
{ "dhcp.", AID_DHCP },
|
{ "dhcp.", AID_DHCP, 0 },
|
||||||
{ "vpn.", AID_SYSTEM },
|
{ "vpn.", AID_SYSTEM, 0 },
|
||||||
{ "vpn.", AID_VPN },
|
{ "vpn.", AID_VPN, 0 },
|
||||||
{ "debug.", AID_SHELL },
|
{ "debug.", AID_SHELL, 0 },
|
||||||
{ "log.", AID_SHELL },
|
{ "log.", AID_SHELL, 0 },
|
||||||
{ "service.adb.root", AID_SHELL },
|
{ "service.adb.root", AID_SHELL, 0 },
|
||||||
{ "persist.sys.", AID_SYSTEM },
|
{ "persist.sys.", AID_SYSTEM, 0 },
|
||||||
{ "persist.service.", AID_SYSTEM },
|
{ "persist.service.", AID_SYSTEM, 0 },
|
||||||
{ NULL, 0 }
|
{ NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -86,8 +87,10 @@ struct {
|
||||||
struct {
|
struct {
|
||||||
const char *service;
|
const char *service;
|
||||||
unsigned int uid;
|
unsigned int uid;
|
||||||
|
unsigned int gid;
|
||||||
} control_perms[] = {
|
} control_perms[] = {
|
||||||
{NULL, 0 }
|
{ "dumpstate",AID_SHELL, AID_LOG },
|
||||||
|
{NULL, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -183,7 +186,7 @@ static int property_write(prop_info *pi, const char *value)
|
||||||
*
|
*
|
||||||
* Returns 1 if uid allowed, 0 otherwise.
|
* Returns 1 if uid allowed, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int check_control_perms(const char *name, int uid) {
|
static int check_control_perms(const char *name, int uid, int gid) {
|
||||||
int i;
|
int i;
|
||||||
if (uid == AID_SYSTEM || uid == AID_ROOT)
|
if (uid == AID_SYSTEM || uid == AID_ROOT)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
@ -191,8 +194,10 @@ static int check_control_perms(const char *name, int uid) {
|
||||||
/* Search the ACL */
|
/* Search the ACL */
|
||||||
for (i = 0; control_perms[i].service; i++) {
|
for (i = 0; control_perms[i].service; i++) {
|
||||||
if (strcmp(control_perms[i].service, name) == 0) {
|
if (strcmp(control_perms[i].service, name) == 0) {
|
||||||
if (control_perms[i].uid == uid)
|
if ((uid && control_perms[i].uid == uid) ||
|
||||||
|
(gid && control_perms[i].gid == gid)) {
|
||||||
return 1;
|
return 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -202,7 +207,7 @@ static int check_control_perms(const char *name, int uid) {
|
||||||
* Checks permissions for setting system properties.
|
* Checks permissions for setting system properties.
|
||||||
* Returns 1 if uid allowed, 0 otherwise.
|
* Returns 1 if uid allowed, 0 otherwise.
|
||||||
*/
|
*/
|
||||||
static int check_perms(const char *name, unsigned int uid)
|
static int check_perms(const char *name, unsigned int uid, int gid)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
if (uid == 0)
|
if (uid == 0)
|
||||||
|
|
@ -215,7 +220,8 @@ static int check_perms(const char *name, unsigned int uid)
|
||||||
int tmp;
|
int tmp;
|
||||||
if (strncmp(property_perms[i].prefix, name,
|
if (strncmp(property_perms[i].prefix, name,
|
||||||
strlen(property_perms[i].prefix)) == 0) {
|
strlen(property_perms[i].prefix)) == 0) {
|
||||||
if (property_perms[i].uid == uid) {
|
if ((uid && property_perms[i].uid == uid) ||
|
||||||
|
(gid && property_perms[i].gid == gid)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -373,14 +379,14 @@ void handle_property_set_fd(int fd)
|
||||||
msg.value[PROP_VALUE_MAX-1] = 0;
|
msg.value[PROP_VALUE_MAX-1] = 0;
|
||||||
|
|
||||||
if(memcmp(msg.name,"ctl.",4) == 0) {
|
if(memcmp(msg.name,"ctl.",4) == 0) {
|
||||||
if (check_control_perms(msg.value, cr.uid)) {
|
if (check_control_perms(msg.value, cr.uid, cr.gid)) {
|
||||||
handle_control_message((char*) msg.name + 4, (char*) msg.value);
|
handle_control_message((char*) msg.name + 4, (char*) msg.value);
|
||||||
} else {
|
} else {
|
||||||
ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n",
|
ERROR("sys_prop: Unable to %s service ctl [%s] uid: %d pid:%d\n",
|
||||||
msg.name + 4, msg.value, cr.uid, cr.pid);
|
msg.name + 4, msg.value, cr.uid, cr.pid);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (check_perms(msg.name, cr.uid)) {
|
if (check_perms(msg.name, cr.uid, cr.gid)) {
|
||||||
property_set((char*) msg.name, (char*) msg.value);
|
property_set((char*) msg.name, (char*) msg.value);
|
||||||
} else {
|
} else {
|
||||||
ERROR("sys_prop: permission denied uid:%d name:%s\n",
|
ERROR("sys_prop: permission denied uid:%d name:%s\n",
|
||||||
|
|
|
||||||
|
|
@ -352,3 +352,7 @@ service keystore /system/bin/keystore
|
||||||
group keystore
|
group keystore
|
||||||
socket keystore stream 666
|
socket keystore stream 666
|
||||||
|
|
||||||
|
service dumpstate /system/bin/dumpstate -s
|
||||||
|
socket dumpstate stream 0660 shell log
|
||||||
|
disabled
|
||||||
|
oneshot
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue