Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc57d4ce authored by Brian Swetland's avatar Brian Swetland
Browse files

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
parent 5988ea72
Loading
Loading
Loading
Loading
+48 −29
Original line number Original line Diff line number Diff line
@@ -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;

    if (attr) {
        node->dp.attr = strdup(attr);
        if (!node->dp.attr)
            return -ENOMEM;
            return -ENOMEM;
    }


    memcpy(node->dp.name, name, size);
    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;


    if (attr)
        list_add_tail(&sys_perms, &node->plist);
    else
        list_add_tail(&dev_perms, &node->plist);
        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]);
+2 −1
Original line number Original line Diff line number Diff line
@@ -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 */
+11 −2
Original line number Original line Diff line number Diff line
@@ -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);
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);