diff options
-rw-r--r-- | init/util.c | 45 |
1 files changed, 34 insertions, 11 deletions
diff --git a/init/util.c b/init/util.c index 9aaa77d..5efd5be 100644 --- a/init/util.c +++ b/init/util.c @@ -524,31 +524,50 @@ int make_dir(const char *path, mode_t mode) return rc; } -int restorecon(const char *pathname) +static int restorecon_sb(const char *pathname, const struct stat *sb) { char *secontext = NULL; - struct stat sb; + char *oldsecontext = NULL; int i; - if (is_selinux_enabled() <= 0 || !sehandle) - return 0; - - if (lstat(pathname, &sb) < 0) - return -errno; - if (selabel_lookup(sehandle, &secontext, pathname, sb.st_mode) < 0) + if (selabel_lookup(sehandle, &secontext, pathname, sb->st_mode) < 0) return -errno; - if (lsetfilecon(pathname, secontext) < 0) { + + if (lgetfilecon(pathname, &oldsecontext) < 0) { freecon(secontext); return -errno; } + + if (strcmp(oldsecontext, secontext) != 0) { + if (lsetfilecon(pathname, secontext) < 0) { + freecon(oldsecontext); + freecon(secontext); + return -errno; + } + } + freecon(oldsecontext); freecon(secontext); return 0; } +int restorecon(const char *pathname) +{ + struct stat sb; + + if (is_selinux_enabled() <= 0 || !sehandle) + return 0; + + if (lstat(pathname, &sb) < 0) + return -errno; + + return restorecon_sb(pathname, &sb); +} + static int nftw_restorecon(const char* filename, const struct stat* statptr, - int fileflags, struct FTW* pftw) + int fileflags __attribute__((unused)), + struct FTW* pftw __attribute__((unused))) { - restorecon(filename); + restorecon_sb(filename, statptr); return 0; } @@ -556,5 +575,9 @@ int restorecon_recursive(const char* pathname) { int fd_limit = 20; int flags = FTW_DEPTH | FTW_MOUNT | FTW_PHYS; + + if (is_selinux_enabled() <= 0 || !sehandle) + return 0; + return nftw(pathname, nftw_restorecon, fd_limit, flags); } |