summaryrefslogtreecommitdiff
path: root/libudev/libudev-selinux-private.c
diff options
context:
space:
mode:
Diffstat (limited to 'libudev/libudev-selinux-private.c')
-rw-r--r--libudev/libudev-selinux-private.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/libudev/libudev-selinux-private.c b/libudev/libudev-selinux-private.c
index 84f8b6a63f..2d4463d864 100644
--- a/libudev/libudev-selinux-private.c
+++ b/libudev/libudev-selinux-private.c
@@ -53,7 +53,7 @@ void udev_selinux_lsetfilecon(struct udev *udev, const char *file, unsigned int
if (matchpathcon(file, mode, &scontext) < 0) {
err(udev, "matchpathcon(%s) failed\n", file);
return;
- }
+ }
if (lsetfilecon(file, scontext) < 0)
err(udev, "setfilecon %s failed: %m\n", file);
freecon(scontext);
@@ -65,6 +65,7 @@ void udev_selinux_setfscreatecon(struct udev *udev, const char *file, unsigned i
if (!selinux_enabled)
return;
+
if (matchpathcon(file, mode, &scontext) < 0) {
err(udev, "matchpathcon(%s) failed\n", file);
return;
@@ -81,3 +82,28 @@ void udev_selinux_resetfscreatecon(struct udev *udev)
if (setfscreatecon(selinux_prev_scontext) < 0)
err(udev, "setfscreatecon failed: %m\n");
}
+
+void udev_selinux_setfscreateconat(struct udev *udev, int dirfd, 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(), dirfd);
+ 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_setfscreatecon(udev, file, mode);
+}