Skip to content

Commit bc57d4c

Browse files
committed
init: support owner/permission setting for sysfs attributes of devices
This should be much nicer than peppering init.rc with chown/chmod directives. Also, remove some dead code and obsolete comments. Change-Id: I10895f10a9cf2f1226c8d12976cd3db3743da9ec
1 parent 5988ea7 commit bc57d4c

File tree

4 files changed

+62
-33
lines changed

4 files changed

+62
-33
lines changed

init/devices.c

+48-29
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ static int open_uevent_socket(void)
8484

8585
struct perms_ {
8686
char *name;
87+
char *attr;
8788
mode_t perm;
8889
unsigned int uid;
8990
unsigned int gid;
@@ -94,56 +95,69 @@ struct perm_node {
9495
struct perms_ dp;
9596
struct listnode plist;
9697
};
98+
99+
static list_declare(sys_perms);
97100
static list_declare(dev_perms);
98101

99-
/*
100-
* Permission override when in emulator mode, must be parsed before
101-
* system properties is initalized.
102-
*/
103-
int add_dev_perms(const char *name, mode_t perm, unsigned int uid,
104-
unsigned int gid, unsigned short prefix) {
105-
int size;
106-
char *tmp = 0;
107-
struct perm_node *node = malloc(sizeof (struct perm_node));
102+
int add_dev_perms(const char *name, const char *attr,
103+
mode_t perm, unsigned int uid, unsigned int gid,
104+
unsigned short prefix) {
105+
struct perm_node *node = calloc(1, sizeof(*node));
108106
if (!node)
109107
return -ENOMEM;
110108

111-
size = strlen(name) + 1;
112-
if ((node->dp.name = malloc(size)) == NULL)
109+
node->dp.name = strdup(name);
110+
if (!node->dp.name)
113111
return -ENOMEM;
114112

115-
memcpy(node->dp.name, name, size);
113+
if (attr) {
114+
node->dp.attr = strdup(attr);
115+
if (!node->dp.attr)
116+
return -ENOMEM;
117+
}
118+
116119
node->dp.perm = perm;
117120
node->dp.uid = uid;
118121
node->dp.gid = gid;
119122
node->dp.prefix = prefix;
120123

121-
list_add_tail(&dev_perms, &node->plist);
124+
if (attr)
125+
list_add_tail(&sys_perms, &node->plist);
126+
else
127+
list_add_tail(&dev_perms, &node->plist);
128+
122129
return 0;
123130
}
124131

125-
static int get_device_perm_inner(struct perms_ *perms, const char *path,
126-
unsigned *uid, unsigned *gid, mode_t *perm)
132+
void fixup_sys_perms(const char *upath)
127133
{
128-
int i;
129-
for(i = 0; perms[i].name; i++) {
134+
char buf[512];
135+
struct listnode *node;
136+
struct perms_ *dp;
130137

131-
if(perms[i].prefix) {
132-
if(strncmp(path, perms[i].name, strlen(perms[i].name)))
138+
/* upaths omit the "/sys" that paths in this list
139+
* contain, so we add 4 when comparing...
140+
*/
141+
list_for_each(node, &sys_perms) {
142+
dp = &(node_to_item(node, struct perm_node, plist))->dp;
143+
if (dp->prefix) {
144+
if (strncmp(upath, dp->name + 4, strlen(dp->name + 4)))
133145
continue;
134146
} else {
135-
if(strcmp(path, perms[i].name))
147+
if (strcmp(upath, dp->name + 4))
136148
continue;
137149
}
138-
*uid = perms[i].uid;
139-
*gid = perms[i].gid;
140-
*perm = perms[i].perm;
141-
return 0;
150+
151+
if ((strlen(upath) + strlen(dp->attr) + 6) > sizeof(buf))
152+
return;
153+
154+
sprintf(buf,"/sys%s/%s", upath, dp->attr);
155+
INFO("fixup %s %d %d 0%o\n", buf, dp->uid, dp->gid, dp->perm);
156+
chown(buf, dp->uid, dp->gid);
157+
chmod(buf, dp->perm);
142158
}
143-
return -1;
144159
}
145160

146-
/* First checks for emulator specific permissions specified in /proc/cmdline. */
147161
static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
148162
{
149163
mode_t perm;
@@ -175,7 +189,9 @@ static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
175189
return 0600;
176190
}
177191

178-
static void make_device(const char *path, int block, int major, int minor)
192+
static void make_device(const char *path,
193+
const char *upath,
194+
int block, int major, int minor)
179195
{
180196
unsigned uid;
181197
unsigned gid;
@@ -334,7 +350,10 @@ static void handle_device_event(struct uevent *uevent)
334350
int block;
335351
int i;
336352

337-
/* if it's not a /dev device, nothing to do */
353+
if (!strcmp(uevent->action,"add"))
354+
fixup_sys_perms(uevent->path);
355+
356+
/* if it's not a /dev device, nothing else to do */
338357
if((uevent->major < 0) || (uevent->minor < 0))
339358
return;
340359

@@ -411,7 +430,7 @@ static void handle_device_event(struct uevent *uevent)
411430
snprintf(devpath, sizeof(devpath), "%s%s", base, name);
412431

413432
if(!strcmp(uevent->action, "add")) {
414-
make_device(devpath, block, uevent->major, uevent->minor);
433+
make_device(devpath, uevent->path, block, uevent->major, uevent->minor);
415434
if (links) {
416435
for (i = 0; links[i]; i++)
417436
make_link(devpath, links[i]);

init/devices.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
extern void handle_device_fd();
2323
extern void device_init(void);
24-
extern int add_dev_perms(const char *name, mode_t perm, unsigned int uid,
24+
extern int add_dev_perms(const char *name, const char *attr,
25+
mode_t perm, unsigned int uid,
2526
unsigned int gid, unsigned short prefix);
2627
int get_device_fd();
2728
#endif /* _INIT_DEVICES_H */

init/ueventd.c

+11-2
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ static int get_android_id(const char *id)
7676
void set_device_permission(int nargs, char **args)
7777
{
7878
char *name;
79+
char *attr = 0;
7980
mode_t perm;
8081
uid_t uid;
8182
gid_t gid;
@@ -90,12 +91,20 @@ void set_device_permission(int nargs, char **args)
9091
if (args[0][0] == '#')
9192
return;
9293

94+
name = args[0];
95+
96+
if (!strncmp(name,"/sys/", 5) && (nargs == 5)) {
97+
INFO("/sys/ rule %s %s\n",args[0],args[1]);
98+
attr = args[1];
99+
args++;
100+
nargs--;
101+
}
102+
93103
if (nargs != 4) {
94104
ERROR("invalid line ueventd.rc line for '%s'\n", args[0]);
95105
return;
96106
}
97107

98-
name = args[0];
99108
/* If path starts with mtd@ lookup the mount number. */
100109
if (!strncmp(name, "mtd@", 4)) {
101110
int n = mtd_name_to_number(name + 4);
@@ -133,6 +142,6 @@ void set_device_permission(int nargs, char **args)
133142
}
134143
gid = ret;
135144

136-
add_dev_perms(name, perm, uid, gid, prefix);
145+
add_dev_perms(name, attr, perm, uid, gid, prefix);
137146
free(tmp);
138147
}

init/ueventd_parser.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
#ifndef _INIT_UEVENTD_PARSER_H_
1818
#define _INIT_UEVENTD_PARSER_H_
1919

20-
#define UEVENTD_PARSER_MAXARGS 4
20+
#define UEVENTD_PARSER_MAXARGS 5
2121

2222
int ueventd_parse_config_file(const char *fn);
2323
void set_device_permission(int nargs, char **args);

0 commit comments

Comments
 (0)