From: Harald Hoyer <harald@xxxxxxxxxx> Set the selinux context on /lib/udev/devices copy, even if the file already exists. --- libudev/libudev-private.h | 2 ++ libudev/libudev-selinux-private.c | 28 ++++++++++++++++++++++++++++ udev/udevd.c | 1 + 3 files changed, 31 insertions(+), 0 deletions(-) diff --git a/libudev/libudev-private.h b/libudev/libudev-private.h index f95be53..de6735c 100644 --- a/libudev/libudev-private.h +++ b/libudev/libudev-private.h @@ -233,6 +233,7 @@ unsigned long long usec_monotonic(void); static inline void udev_selinux_init(struct udev *udev) {} static inline void udev_selinux_exit(struct udev *udev) {} static inline void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode) {} +static inline void udev_selinux_lsetfileconat(struct udev *udev, int dfd, const char *file, unsigned int mode) {} static inline void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode) {} static inline void udev_selinux_setfscreateconat(struct udev *udev, int dfd, const char *file, unsigned int mode) {} static inline void udev_selinux_resetfscreatecon(struct udev *udev) {} @@ -240,6 +241,7 @@ static inline void udev_selinux_resetfscreatecon(struct udev *udev) {} void udev_selinux_init(struct udev *udev); void udev_selinux_exit(struct udev *udev); void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int mode); +void udev_selinux_lsetfileconat(struct udev *udev, int dfd, const char *file, unsigned int mode); void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode); void udev_selinux_setfscreateconat(struct udev *udev, int dfd, const char *file, unsigned int mode); void udev_selinux_resetfscreatecon(struct udev *udev); diff --git a/libudev/libudev-selinux-private.c b/libudev/libudev-selinux-private.c index cb06a28..f482ea8 100644 --- a/libudev/libudev-selinux-private.c +++ b/libudev/libudev-selinux-private.c @@ -59,6 +59,34 @@ void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int freecon(scontext); } +void udev_selinux_lsetfileconat(struct udev *udev, int dfd, const char *file, unsigned int mode) +{ + char filename[UTIL_PATH_SIZE]; + + if (!selinux_enabled) + return; + + /* resolve relative filename */ + if (file[0] != '/') { + char procfd[UTIL_PATH_SIZE]; + char target[UTIL_PATH_SIZE]; + ssize_t len; + + snprintf(procfd, sizeof(procfd), "/proc/%u/fd/%u", getpid(), dfd); + len = readlink(procfd, target, sizeof(target)); + if (len <= 0 || len == sizeof(target)) + return; + target[len] = '\0'; + + util_strscpyl(filename, sizeof(filename), target, "/", file, NULL); + file = filename; + } + + udev_selinux_lsetfilecon(udev, file, mode) +} + + + void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned int mode) { security_context_t scontext = NULL; diff --git a/udev/udevd.c b/udev/udevd.c index aa2e365..8ebefd0 100644 --- a/udev/udevd.c +++ b/udev/udevd.c @@ -851,6 +851,7 @@ static int copy_dir(struct udev *udev, DIR *dir_from, DIR *dir_to, int maxdepth) fchmodat(dirfd(dir_to), dent->d_name, stats.st_mode & 0777, 0); fchownat(dirfd(dir_to), dent->d_name, stats.st_uid, stats.st_gid, 0); } else { + udev_selinux_lsetfileconat(udev, dirfd(dir_to), dent->d_name, stats.st_mode & 0777); utimensat(dirfd(dir_to), dent->d_name, NULL, 0); } udev_selinux_resetfscreatecon(udev); -- To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html