New paste Repaste Download
$ cat 0001-selinux-use-the-labeldb-for-a-manual-transition-when.patch
From e99be9903c9a54f045f5006146348e4cabaae281 Mon Sep 17 00:00:00 2001
From: Rahul Sandhu <nvraxn@gmail.com>
Date: Mon, 2 Jun 2025 17:35:03 +0100
Subject: [PATCH] selinux: use the labeldb for a manual transition when
creating dirs
Signed-off-by: Rahul Sandhu <nvraxn@gmail.com>
---
meson.build       |   9 +++-
meson_options.txt |   5 ++
src/fs_utils.cc   | 128 ++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 141 insertions(+), 1 deletion(-)
diff --git a/meson.build b/meson.build
index 770b982..a0d349f 100644
--- a/meson.build
+++ b/meson.build
@@ -22,6 +22,12 @@ scdoc_dep = dependency(
    native: true
)
+libselinux_dep = dependency(
+    'libselinux',
+    version: '>=2.1.9',
+    required: get_option('support_selinux')
+)
+
have_dinit = get_option('dinit').enabled()
have_runit = get_option('runit').enabled()
@@ -31,6 +37,7 @@ conf_data.set_quoted('CONF_PATH', join_paths(
    get_option('prefix'), get_option('sysconfdir'), 'turnstile'
))
conf_data.set10('MANAGE_RUNDIR', get_option('manage_rundir'))
+conf_data.set10('HAVE_SELINUX', libselinux_dep.found())
conf_data.set('HAVE_PAM_MISC', pam_misc_dep.found())
@@ -82,7 +89,7 @@ daemon = executable(
    'turnstiled', daemon_sources,
    include_directories: extra_inc,
    install: true,
-    dependencies: [rt_dep, pam_dep, pam_misc_dep],
+    dependencies: [rt_dep, pam_dep, pam_misc_dep, libselinux_dep],
    gnu_symbol_visibility: 'hidden'
)
diff --git a/meson_options.txt b/meson_options.txt
index 29abb69..4d3af0c 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -38,6 +38,11 @@ option('manage_rundir',
    description: 'Whether to manage rundir by default'
)
+option('support_selinux',
+    type: 'feature', value: 'auto',
+    description: 'Whether to support SELinux',
+)
+
option('man',
    type: 'boolean', value: true,
    description: 'Whether to generate manpages'
diff --git a/src/fs_utils.cc b/src/fs_utils.cc
index ac91921..6ae8d0f 100644
--- a/src/fs_utils.cc
+++ b/src/fs_utils.cc
@@ -10,11 +10,59 @@
#include "turnstiled.hh"
+#ifdef HAVE_SELINUX
+#include <selinux/label.h>
+#include <selinux/selinux.h>
+#endif
+
int dir_make_at(int dfd, char const *dname, mode_t mode) {
    int sdfd = openat(dfd, dname, O_RDONLY | O_NOFOLLOW);
    struct stat st;
    int reterr = 0;
    int omask = umask(0);
+
+#ifdef HAVE_SELINUX
+    // We can't rely on policy transitions to set the user field of the context
+    // correctly as that depends on the seuser db, so calculate the context to
+    // create the runtimedir with ourselves.
+    char *path = nullptr;
+    char *context = nullptr;
+    {
+        char procfd[64];
+        ssize_t len;
+        snprintf(procfd, sizeof(procfd), "/proc/self/fd/%d", dfd);
+        char dfd_path[PATH_MAX];
+        len = readlink(procfd, dfd_path, sizeof(dfd_path)-1);
+        if (len < 0) {
+            goto ret_err;
+        }
+        dfd_path[len] = '\0';
+        path = (char *)malloc(strlen(dfd_path) + 1 + strlen(dname) + 2);
+        if (!path) {
+            goto ret_err;
+        }
+        sprintf(path, "%s/%s", dfd_path, dname);
+
+        struct selabel_handle *sehandle =
+            selabel_open(SELABEL_CTX_FILE, nullptr, 0);
+        if (!sehandle) {
+            perror("selabel_open");
+            goto ret_err;
+        }
+        if (selabel_lookup_raw(sehandle, &context, path, mode) < 0) {
+            perror("selabel_lookup_raw");
+            selabel_close(sehandle);
+            goto ret_err;
+        }
+        selabel_close(sehandle);
+        if (setfscreatecon_raw(context) < 0) {
+            perror("setfscreatecon_raw");
+            goto ret_err;
+        }
+    }
+    print_err ("selinux: %s | %s", path, context);
+#endif
+
    if (fstat(sdfd, &st) || !S_ISDIR(st.st_mode)) {
        close(sdfd);
        if (mkdirat(dfd, dname, mode)) {
@@ -29,6 +77,7 @@ int dir_make_at(int dfd, char const *dname, mode_t mode) {
            goto ret_err;
        }
    } else {
+        // TODO: dir already exists, call lsetfilecon.
        /* dir_clear_contents closes the descriptor, we need to keep it */
        int nfd;
        if ((fchmod(sdfd, mode) < 0) || ((nfd = dup(sdfd)) < 0)) {
@@ -39,9 +88,34 @@ int dir_make_at(int dfd, char const *dname, mode_t mode) {
            goto ret_err;
        }
    }
+
+#ifdef HAVE_SELINUX
+    // Reset fs creation context so new objects are labelled correctly.
+    if (setfscreatecon(nullptr) < 0) {
+        perror("setfscreatecon");
+        goto ret_err;
+    }
+    if (context) {
+        free(context);
+    }
+    if (path) {
+        free(path);
+    }
+#endif
+
    umask(omask);
    return sdfd;
+
ret_err:
+#ifdef HAVE_SELINUX
+    setfscreatecon(nullptr);
+    if (context) {
+        free(context);
+    }
+    if (path) {
+        free(path);
+    }
+#endif
    umask(omask);
    if (sdfd >= 0) {
        close(sdfd);
@@ -97,6 +171,46 @@ bool rundir_make(char *rundir, unsigned int uid, unsigned int gid) {
        sl = std::strchr(dirbase, '/');
    }
    umask(omask);
+
+#ifdef HAVE_SELINUX
+    // We can't rely on policy transitions to set the user field of the context
+    // correctly as that depends on the seuser db, so calculate the context to
+    // create the runtimedir with ourselves.
+    char *context = nullptr;
+    {
+        struct selabel_handle *sehandle =
+            selabel_open(SELABEL_CTX_FILE, nullptr, 0);
+        if (!sehandle) {
+            print_err(
+                "rundir: failed to make rundir %s (%s)",
+                rundir, strerror(errno)
+            );
+            close(bfd);
+            return false;
+        }
+        if (selabel_lookup_raw(sehandle, &context, rundir, 0700) < 0) {
+            print_err(
+                "rundir: failed to make rundir %s (%s)",
+                rundir, strerror(errno)
+            );
+            selabel_close(sehandle);
+            close(bfd);
+            return false;
+        }
+        selabel_close(sehandle);
+        if (setfscreatecon_raw(context) < 0) {
+            print_err(
+                "rundir: failed to make rundir %s (%s)",
+                rundir, strerror(errno)
+            );
+            close(bfd);
+            return false;
+        }
+    }
+    print_err ("selinux: %s | %s", rundir, context);
+#endif
+
+    // TODO: lsetfilecon for dir already existing.
    /* now create rundir or at least sanitize its perms */
    if (
        (fstatat(bfd, dirbase, &dstat, AT_SYMLINK_NOFOLLOW) < 0) ||
@@ -115,6 +229,20 @@ bool rundir_make(char *rundir, unsigned int uid, unsigned int gid) {
        close(bfd);
        return false;
    }
+
+#ifdef HAVE_SELINUX
+    // Reset fs creation context so new objects are labelled correctly.
+    if (setfscreatecon(nullptr) < 0) {
+        perror("setfscreatecon");
+        close(bfd);
+        free(context);
+        return false;
+    }
+    if (context) {
+        free(context);
+    }
+#endif
+
    if (fchownat(bfd, dirbase, uid, gid, AT_SYMLINK_NOFOLLOW) < 0) {
        print_err("rundir: fchownat failed for rundir (%s)", strerror(errno));
        close(bfd);
--
2.49.0
$ cat 0001-turnstiled-use-labeldb-when-creating-user-owned-fifo.patch
From d809f35f6c0dbd0f30559eafaaa614d484f7b230 Mon Sep 17 00:00:00 2001
From: Rahul Sandhu <nvraxn@gmail.com>
Date: Tue, 3 Jun 2025 18:10:25 +0100
Subject: [PATCH] turnstiled: use labeldb when creating user-owned fifofile
Signed-off-by: Rahul Sandhu <nvraxn@gmail.com>
---
src/turnstiled.cc | 52 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 52 insertions(+)
diff --git a/src/turnstiled.cc b/src/turnstiled.cc
index cf9e6d3..cf8580f 100644
--- a/src/turnstiled.cc
+++ b/src/turnstiled.cc
@@ -33,6 +33,11 @@
#include "turnstiled.hh"
#include "utils.hh"
+#ifdef HAVE_SELINUX
+#include <selinux/label.h>
+#include <selinux/selinux.h>
+#endif
+
#ifndef CONF_PATH
#error "No CONF_PATH is defined"
#endif
@@ -159,10 +164,57 @@ static bool srv_start(login &lgn) {
    }
    print_dbg("srv: create readiness pipe");
    unlinkat(lgn.dirfd, "ready", 0);
+#ifdef HAVE_SELINUX
+    // We can't rely on policy transitions to set the user field of the context
+    // correctly as that depends on the seuser db, so calculate the context to
+    // create the runtimedir with ourselves.
+    char *context = nullptr;
+    {
+        struct selabel_handle *sehandle =
+            selabel_open(SELABEL_CTX_FILE, nullptr, 0);
+        if (!sehandle) {
+            print_err("srv: failed to make ready pipe (%s)", strerror(errno));
+            return false;
+        }
+        char ready_path[PATH_MAX];
+        if (const int r = std::snprintf(ready_path, sizeof(ready_path),
+                                        "%s/%s/%u/ready", RUN_PATH, SOCK_DIR, lgn.uid);
+            r < 0 || r >= PATH_MAX) {
+            print_err("srv: failed to make ready pipe (%s)", strerror(errno));
+            selabel_close(sehandle);
+            return false;
+        }
+ if (selabel_lookup_raw(sehandle, &context, ready_path, 0700) < 0) {
+            print_err("srv: failed to make ready pipe (%s)", strerror(errno));
+            selabel_close(sehandle);
+            return false;
+        }
+        selabel_close(sehandle);
+        if (setfscreatecon_raw(context) < 0) {
+            print_err("srv: failed to make ready pipe (%s)", strerror(errno));
+            free(context);
+            return false;
+        }
+    }
+#endif
    if (mkfifoat(lgn.dirfd, "ready", 0700) < 0) {
        print_err("srv: failed to make ready pipe (%s)", strerror(errno));
        return false;
    }
+#ifdef HAVE_SELINUX
+    // Reset fs creation context so new objects are labelled correctly.
+    if (context) {
+        free(context);
+    }
+    if (setfscreatecon(nullptr) < 0) {
+        print_err(
+            "srv: failed to set up ready pipe (%s)", strerror(errno)
+        );
+        unlinkat(lgn.dirfd, "ready", 0);
+        lgn.remove_sdir();
+        return false;
+    }
+#endif
    /* ensure it's owned by user too, and open in nonblocking mode */
    if (fchownat(
        lgn.dirfd, "ready", lgn.uid, lgn.gid, AT_SYMLINK_NOFOLLOW
--
2.49.0
Filename: 0001-selinux-use-the-labeldb-for-a-manual-transition-when.patch 0001-turnstiled-use-labeldb-when-creating-user-owned-fifo.patch. Size: 10kb. View raw, , hex, or download this file.

This paste expires on 2025-06-11 21:26:45.330754. Pasted through v1-api.