diff --git a/init/util.c b/init/util.c index 9aaa77d47..5efd5bebe 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 (selabel_lookup(sehandle, &secontext, pathname, sb->st_mode) < 0) + return -errno; + + 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; - if (selabel_lookup(sehandle, &secontext, pathname, sb.st_mode) < 0) - return -errno; - if (lsetfilecon(pathname, secontext) < 0) { - freecon(secontext); - return -errno; - } - freecon(secontext); - return 0; + + 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); }