am bc57d4ce: init: support owner/permission setting for sysfs attributes of devices
This commit is contained in:
commit
439b4dfb27
4 changed files with 62 additions and 33 deletions
|
|
@ -84,6 +84,7 @@ static int open_uevent_socket(void)
|
||||||
|
|
||||||
struct perms_ {
|
struct perms_ {
|
||||||
char *name;
|
char *name;
|
||||||
|
char *attr;
|
||||||
mode_t perm;
|
mode_t perm;
|
||||||
unsigned int uid;
|
unsigned int uid;
|
||||||
unsigned int gid;
|
unsigned int gid;
|
||||||
|
|
@ -94,56 +95,69 @@ struct perm_node {
|
||||||
struct perms_ dp;
|
struct perms_ dp;
|
||||||
struct listnode plist;
|
struct listnode plist;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static list_declare(sys_perms);
|
||||||
static list_declare(dev_perms);
|
static list_declare(dev_perms);
|
||||||
|
|
||||||
/*
|
int add_dev_perms(const char *name, const char *attr,
|
||||||
* Permission override when in emulator mode, must be parsed before
|
mode_t perm, unsigned int uid, unsigned int gid,
|
||||||
* system properties is initalized.
|
unsigned short prefix) {
|
||||||
*/
|
struct perm_node *node = calloc(1, sizeof(*node));
|
||||||
int add_dev_perms(const char *name, mode_t perm, unsigned int uid,
|
|
||||||
unsigned int gid, unsigned short prefix) {
|
|
||||||
int size;
|
|
||||||
char *tmp = 0;
|
|
||||||
struct perm_node *node = malloc(sizeof (struct perm_node));
|
|
||||||
if (!node)
|
if (!node)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
size = strlen(name) + 1;
|
node->dp.name = strdup(name);
|
||||||
if ((node->dp.name = malloc(size)) == NULL)
|
if (!node->dp.name)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
memcpy(node->dp.name, name, size);
|
if (attr) {
|
||||||
|
node->dp.attr = strdup(attr);
|
||||||
|
if (!node->dp.attr)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
node->dp.perm = perm;
|
node->dp.perm = perm;
|
||||||
node->dp.uid = uid;
|
node->dp.uid = uid;
|
||||||
node->dp.gid = gid;
|
node->dp.gid = gid;
|
||||||
node->dp.prefix = prefix;
|
node->dp.prefix = prefix;
|
||||||
|
|
||||||
list_add_tail(&dev_perms, &node->plist);
|
if (attr)
|
||||||
|
list_add_tail(&sys_perms, &node->plist);
|
||||||
|
else
|
||||||
|
list_add_tail(&dev_perms, &node->plist);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int get_device_perm_inner(struct perms_ *perms, const char *path,
|
void fixup_sys_perms(const char *upath)
|
||||||
unsigned *uid, unsigned *gid, mode_t *perm)
|
|
||||||
{
|
{
|
||||||
int i;
|
char buf[512];
|
||||||
for(i = 0; perms[i].name; i++) {
|
struct listnode *node;
|
||||||
|
struct perms_ *dp;
|
||||||
|
|
||||||
if(perms[i].prefix) {
|
/* upaths omit the "/sys" that paths in this list
|
||||||
if(strncmp(path, perms[i].name, strlen(perms[i].name)))
|
* contain, so we add 4 when comparing...
|
||||||
|
*/
|
||||||
|
list_for_each(node, &sys_perms) {
|
||||||
|
dp = &(node_to_item(node, struct perm_node, plist))->dp;
|
||||||
|
if (dp->prefix) {
|
||||||
|
if (strncmp(upath, dp->name + 4, strlen(dp->name + 4)))
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
if(strcmp(path, perms[i].name))
|
if (strcmp(upath, dp->name + 4))
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
*uid = perms[i].uid;
|
|
||||||
*gid = perms[i].gid;
|
if ((strlen(upath) + strlen(dp->attr) + 6) > sizeof(buf))
|
||||||
*perm = perms[i].perm;
|
return;
|
||||||
return 0;
|
|
||||||
|
sprintf(buf,"/sys%s/%s", upath, dp->attr);
|
||||||
|
INFO("fixup %s %d %d 0%o\n", buf, dp->uid, dp->gid, dp->perm);
|
||||||
|
chown(buf, dp->uid, dp->gid);
|
||||||
|
chmod(buf, dp->perm);
|
||||||
}
|
}
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* First checks for emulator specific permissions specified in /proc/cmdline. */
|
|
||||||
static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
|
static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
|
||||||
{
|
{
|
||||||
mode_t perm;
|
mode_t perm;
|
||||||
|
|
@ -175,7 +189,9 @@ static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid)
|
||||||
return 0600;
|
return 0600;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_device(const char *path, int block, int major, int minor)
|
static void make_device(const char *path,
|
||||||
|
const char *upath,
|
||||||
|
int block, int major, int minor)
|
||||||
{
|
{
|
||||||
unsigned uid;
|
unsigned uid;
|
||||||
unsigned gid;
|
unsigned gid;
|
||||||
|
|
@ -334,7 +350,10 @@ static void handle_device_event(struct uevent *uevent)
|
||||||
int block;
|
int block;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* if it's not a /dev device, nothing to do */
|
if (!strcmp(uevent->action,"add"))
|
||||||
|
fixup_sys_perms(uevent->path);
|
||||||
|
|
||||||
|
/* if it's not a /dev device, nothing else to do */
|
||||||
if((uevent->major < 0) || (uevent->minor < 0))
|
if((uevent->major < 0) || (uevent->minor < 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -411,7 +430,7 @@ static void handle_device_event(struct uevent *uevent)
|
||||||
snprintf(devpath, sizeof(devpath), "%s%s", base, name);
|
snprintf(devpath, sizeof(devpath), "%s%s", base, name);
|
||||||
|
|
||||||
if(!strcmp(uevent->action, "add")) {
|
if(!strcmp(uevent->action, "add")) {
|
||||||
make_device(devpath, block, uevent->major, uevent->minor);
|
make_device(devpath, uevent->path, block, uevent->major, uevent->minor);
|
||||||
if (links) {
|
if (links) {
|
||||||
for (i = 0; links[i]; i++)
|
for (i = 0; links[i]; i++)
|
||||||
make_link(devpath, links[i]);
|
make_link(devpath, links[i]);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,8 @@
|
||||||
|
|
||||||
extern void handle_device_fd();
|
extern void handle_device_fd();
|
||||||
extern void device_init(void);
|
extern void device_init(void);
|
||||||
extern int add_dev_perms(const char *name, mode_t perm, unsigned int uid,
|
extern int add_dev_perms(const char *name, const char *attr,
|
||||||
|
mode_t perm, unsigned int uid,
|
||||||
unsigned int gid, unsigned short prefix);
|
unsigned int gid, unsigned short prefix);
|
||||||
int get_device_fd();
|
int get_device_fd();
|
||||||
#endif /* _INIT_DEVICES_H */
|
#endif /* _INIT_DEVICES_H */
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ static int get_android_id(const char *id)
|
||||||
void set_device_permission(int nargs, char **args)
|
void set_device_permission(int nargs, char **args)
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
|
char *attr = 0;
|
||||||
mode_t perm;
|
mode_t perm;
|
||||||
uid_t uid;
|
uid_t uid;
|
||||||
gid_t gid;
|
gid_t gid;
|
||||||
|
|
@ -90,12 +91,20 @@ void set_device_permission(int nargs, char **args)
|
||||||
if (args[0][0] == '#')
|
if (args[0][0] == '#')
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
name = args[0];
|
||||||
|
|
||||||
|
if (!strncmp(name,"/sys/", 5) && (nargs == 5)) {
|
||||||
|
INFO("/sys/ rule %s %s\n",args[0],args[1]);
|
||||||
|
attr = args[1];
|
||||||
|
args++;
|
||||||
|
nargs--;
|
||||||
|
}
|
||||||
|
|
||||||
if (nargs != 4) {
|
if (nargs != 4) {
|
||||||
ERROR("invalid line ueventd.rc line for '%s'\n", args[0]);
|
ERROR("invalid line ueventd.rc line for '%s'\n", args[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
name = args[0];
|
|
||||||
/* If path starts with mtd@ lookup the mount number. */
|
/* If path starts with mtd@ lookup the mount number. */
|
||||||
if (!strncmp(name, "mtd@", 4)) {
|
if (!strncmp(name, "mtd@", 4)) {
|
||||||
int n = mtd_name_to_number(name + 4);
|
int n = mtd_name_to_number(name + 4);
|
||||||
|
|
@ -133,6 +142,6 @@ void set_device_permission(int nargs, char **args)
|
||||||
}
|
}
|
||||||
gid = ret;
|
gid = ret;
|
||||||
|
|
||||||
add_dev_perms(name, perm, uid, gid, prefix);
|
add_dev_perms(name, attr, perm, uid, gid, prefix);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@
|
||||||
#ifndef _INIT_UEVENTD_PARSER_H_
|
#ifndef _INIT_UEVENTD_PARSER_H_
|
||||||
#define _INIT_UEVENTD_PARSER_H_
|
#define _INIT_UEVENTD_PARSER_H_
|
||||||
|
|
||||||
#define UEVENTD_PARSER_MAXARGS 4
|
#define UEVENTD_PARSER_MAXARGS 5
|
||||||
|
|
||||||
int ueventd_parse_config_file(const char *fn);
|
int ueventd_parse_config_file(const char *fn);
|
||||||
void set_device_permission(int nargs, char **args);
|
void set_device_permission(int nargs, char **args);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue