@@ -84,6 +84,7 @@ static int open_uevent_socket(void)
84
84
85
85
struct perms_ {
86
86
char * name ;
87
+ char * attr ;
87
88
mode_t perm ;
88
89
unsigned int uid ;
89
90
unsigned int gid ;
@@ -94,56 +95,69 @@ struct perm_node {
94
95
struct perms_ dp ;
95
96
struct listnode plist ;
96
97
};
98
+
99
+ static list_declare (sys_perms );
97
100
static list_declare (dev_perms );
98
101
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 ));
108
106
if (!node )
109
107
return - ENOMEM ;
110
108
111
- size = strlen (name ) + 1 ;
112
- if (( node -> dp .name = malloc ( size )) == NULL )
109
+ node -> dp . name = strdup (name );
110
+ if (! node -> dp .name )
113
111
return - ENOMEM ;
114
112
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
+
116
119
node -> dp .perm = perm ;
117
120
node -> dp .uid = uid ;
118
121
node -> dp .gid = gid ;
119
122
node -> dp .prefix = prefix ;
120
123
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
+
122
129
return 0 ;
123
130
}
124
131
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 )
127
133
{
128
- int i ;
129
- for (i = 0 ; perms [i ].name ; i ++ ) {
134
+ char buf [512 ];
135
+ struct listnode * node ;
136
+ struct perms_ * dp ;
130
137
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 )))
133
145
continue ;
134
146
} else {
135
- if (strcmp (path , perms [ i ]. name ))
147
+ if (strcmp (upath , dp -> name + 4 ))
136
148
continue ;
137
149
}
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 );
142
158
}
143
- return -1 ;
144
159
}
145
160
146
- /* First checks for emulator specific permissions specified in /proc/cmdline. */
147
161
static mode_t get_device_perm (const char * path , unsigned * uid , unsigned * gid )
148
162
{
149
163
mode_t perm ;
@@ -175,7 +189,9 @@ static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
175
189
return 0600 ;
176
190
}
177
191
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 )
179
195
{
180
196
unsigned uid ;
181
197
unsigned gid ;
@@ -334,7 +350,10 @@ static void handle_device_event(struct uevent *uevent)
334
350
int block ;
335
351
int i ;
336
352
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 */
338
357
if ((uevent -> major < 0 ) || (uevent -> minor < 0 ))
339
358
return ;
340
359
@@ -411,7 +430,7 @@ static void handle_device_event(struct uevent *uevent)
411
430
snprintf (devpath , sizeof (devpath ), "%s%s" , base , name );
412
431
413
432
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 );
415
434
if (links ) {
416
435
for (i = 0 ; links [i ]; i ++ )
417
436
make_link (devpath , links [i ]);
0 commit comments