From mboxrd@z Thu Jan 1 00:00:00 1970 From: harald@redhat.com Date: Fri, 21 Jan 2011 15:41:49 +0000 Subject: [PATCH] udevd.c: set selinux context on /lib/udev/devices copy Message-Id: <1295624509-4918-1-git-send-email-harald@redhat.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linux-hotplug@vger.kernel.org From: Harald Hoyer 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);