diff --git a/init/devices.c b/init/devices.c index 02698eff1..ea9a4b25d 100644 --- a/init/devices.c +++ b/init/devices.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -77,6 +78,7 @@ struct perms_ { unsigned int uid; unsigned int gid; unsigned short prefix; + unsigned short wildcard; }; struct perm_node { @@ -97,7 +99,8 @@ static list_declare(platform_names); int add_dev_perms(const char *name, const char *attr, mode_t perm, unsigned int uid, unsigned int gid, - unsigned short prefix) { + unsigned short prefix, + unsigned short wildcard) { struct perm_node *node = calloc(1, sizeof(*node)); if (!node) return -ENOMEM; @@ -116,6 +119,7 @@ int add_dev_perms(const char *name, const char *attr, node->dp.uid = uid; node->dp.gid = gid; node->dp.prefix = prefix; + node->dp.wildcard = wildcard; if (attr) list_add_tail(&sys_perms, &node->plist); @@ -140,6 +144,9 @@ void fixup_sys_perms(const char *upath) if (dp->prefix) { if (strncmp(upath, dp->name + 4, strlen(dp->name + 4))) continue; + } else if (dp->wildcard) { + if (fnmatch(dp->name + 4, upath, FNM_PATHNAME) != 0) + continue; } else { if (strcmp(upath, dp->name + 4)) continue; @@ -180,6 +187,9 @@ static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid) if (dp->prefix) { if (strncmp(path, dp->name, strlen(dp->name))) continue; + } else if (dp->wildcard) { + if (fnmatch(dp->name, path, FNM_PATHNAME) != 0) + continue; } else { if (strcmp(path, dp->name)) continue; diff --git a/init/devices.h b/init/devices.h index a84fa5827..5d0fe8862 100644 --- a/init/devices.h +++ b/init/devices.h @@ -23,6 +23,7 @@ extern void handle_device_fd(); extern void device_init(void); 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, + unsigned short wildcard); int get_device_fd(); #endif /* _INIT_DEVICES_H */ diff --git a/init/ueventd.c b/init/ueventd.c index 662196dc1..4ad0cb969 100644 --- a/init/ueventd.c +++ b/init/ueventd.c @@ -122,6 +122,7 @@ void set_device_permission(int nargs, char **args) uid_t uid; gid_t gid; int prefix = 0; + int wildcard = 0; char *endptr; int ret; char *tmp = 0; @@ -154,9 +155,13 @@ void set_device_permission(int nargs, char **args) name = tmp; } else { int len = strlen(name); - if (name[len - 1] == '*') { + char *wildcard_chr = strchr(name, '*'); + if ((name[len - 1] == '*') && + (wildcard_chr == (name + len - 1))) { prefix = 1; name[len - 1] = '\0'; + } else if (wildcard_chr) { + wildcard = 1; } } @@ -183,6 +188,6 @@ void set_device_permission(int nargs, char **args) } gid = ret; - add_dev_perms(name, attr, perm, uid, gid, prefix); + add_dev_perms(name, attr, perm, uid, gid, prefix, wildcard); free(tmp); }