From 43d537e0deeb4ba20e13db22e4fc28b87a4621c7 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Wed, 2 Jul 2014 13:08:13 -0700 Subject: ueventd: allow matching symlink names when setting permissions Change-Id: I5f6cc2a25f1236fbe2c7193b65363b7883b9ba2e --- init/devices.c | 51 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/init/devices.c b/init/devices.c index ea9a4b2..58b2704 100644 --- a/init/devices.c +++ b/init/devices.c @@ -170,7 +170,24 @@ void fixup_sys_perms(const char *upath) } } -static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid) +static bool perm_path_matches(const char *path, struct perms_ *dp) +{ + if (dp->prefix) { + if (strncmp(path, dp->name, strlen(dp->name)) == 0) + return true; + } else if (dp->wildcard) { + if (fnmatch(dp->name, path, FNM_PATHNAME) == 0) + return true; + } else { + if (strcmp(path, dp->name) == 0) + return true; + } + + return false; +} + +static mode_t get_device_perm(const char *path, const char **links, + unsigned *uid, unsigned *gid) { mode_t perm; struct listnode *node; @@ -181,22 +198,30 @@ static mode_t get_device_perm(const char *path, unsigned *uid, unsigned *gid) * override ueventd.rc */ list_for_each_reverse(node, &dev_perms) { + bool match = false; + perm_node = node_to_item(node, struct perm_node, plist); dp = &perm_node->dp; - 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; + if (perm_path_matches(path, dp)) { + match = true; } else { - if (strcmp(path, dp->name)) - continue; + if (links) { + int i; + for (i = 0; links[i]; i++) { + if (perm_path_matches(links[i], dp)) { + match = true; + break; + } + } + } + } + + if (match) { + *uid = dp->uid; + *gid = dp->gid; + return dp->perm; } - *uid = dp->uid; - *gid = dp->gid; - return dp->perm; } /* Default if nothing found. */ *uid = 0; @@ -215,7 +240,7 @@ static void make_device(const char *path, dev_t dev; char *secontext = NULL; - mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR); + mode = get_device_perm(path, links, &uid, &gid) | (block ? S_IFBLK : S_IFCHR); if (sehandle) { selabel_lookup_best_match(sehandle, &secontext, path, links, mode); -- cgit v1.1