]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
socket-util: add new helper socket_xattr_supported()
authorLennart Poettering <lennart@amutable.com>
Wed, 3 Jun 2026 09:06:23 +0000 (11:06 +0200)
committerLennart Poettering <lennart@amutable.com>
Tue, 23 Jun 2026 20:55:23 +0000 (22:55 +0200)
TODO.md
src/basic/socket-util.c
src/basic/socket-util.h
src/test/test-socket-util.c

diff --git a/TODO.md b/TODO.md
index 1ebad3fcf847a4bea2d920d259f3cab43f0e7ef6..4d6668dace7a70be4975990e63ea3b7b2407ae0f 100644 (file)
--- a/TODO.md
+++ b/TODO.md
@@ -126,6 +126,8 @@ SPDX-License-Identifier: LGPL-2.1-or-later
 - remove any trace of "cpuacct" cgroup controller, it's a cgroupv1 thing.
   similar "devices"
 
+- drop socket_xattr_supported() once our baseline is kernel 7.0
+
 ## Features
 
 - **report:**
index d8f41f0f9c0d69571ce69530247620e194b864b8..c25e41d77195657171d89c88cf68d256fd8668d9 100644 (file)
@@ -13,6 +13,7 @@
 #include <poll.h>
 #include <stdio.h>
 #include <sys/ioctl.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include "alloc-util.h"
@@ -21,6 +22,7 @@
 #include "fd-util.h"
 #include "format-ifname.h"
 #include "format-util.h"
+#include "fs-util.h"
 #include "in-addr-util.h"
 #include "io-util.h"
 #include "log.h"
@@ -36,6 +38,8 @@
 #include "string-util.h"
 #include "strv.h"
 #include "sysctl-util.h"
+#include "tmpfile-util.h"
+#include "xattr-util.h"
 
 #if ENABLE_IDN
 #  define IDN_FLAGS NI_IDN
@@ -1891,3 +1895,41 @@ int tos_to_priority(uint8_t tos) {
                 return TC_PRIO_BESTEFFORT;
         }
 }
+
+int socket_xattr_supported(void) {
+        int r;
+
+        // FIXME: Drop this check once Linux 7.0 becomes our baseline
+
+        /* Checks if socket inodes may have xattrs on this kernel. This should pass on kernel 7.0, fail on
+         * older kernels */
+
+        static int cached = -1;
+        if (cached >= 0)
+                return cached;
+
+        const char *t;
+        r = tmp_dir(&t);
+        if (r < 0)
+                return r;
+
+        _cleanup_free_ char *sp = NULL;
+        r = tempfn_random_child(t, "sockxattrtest", &sp);
+        if (r < 0)
+                return r;
+
+        if (mknod(sp, S_IFSOCK | 0600, /* dev= */ 0) < 0)
+                return -errno;
+
+        _cleanup_(unlink_and_freep) char *sp_destroy = TAKE_PTR(sp);
+
+        /* Old kernels return EPERM. But let's also check for more appropriate error codes, to be friendly to
+         * seccomp policies */
+        r = xsetxattr(AT_FDCWD, sp_destroy, /* at_flags= */ 0, "user.testxxx", "1");
+        if (ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EPERM)
+                return (cached = false);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to set test xattr on socket inode '%s': %m", sp_destroy);
+
+        return (cached = true);
+}
index b3a2733b74a0ea2779cb5096b46f53074623c7be..f9d6ddaaad0e560efdafdcba4a21389618b1f179 100644 (file)
@@ -268,3 +268,5 @@ int socket_get_cookie(int fd, uint64_t *ret);
 void cmsg_close_all(struct msghdr *mh);
 
 int tos_to_priority(uint8_t tos);
+
+int socket_xattr_supported(void);
index 713844b09b720ceb24b92d8958052112cef65c94..038140d4c578c31f178af6a39539e24c73e208b4 100644 (file)
@@ -4,6 +4,7 @@
 #include <grp.h>
 #include <linux/pkt_sched.h>
 #include <netinet/ip.h>
+#include <sys/stat.h>
 #include <unistd.h>
 
 #include "alloc-util.h"
@@ -550,4 +551,16 @@ TEST(tos_to_priority) {
         ASSERT_EQ(tos_to_priority(0xff), TC_PRIO_CONTROL);
 }
 
+TEST(socket_xattr_supported) {
+        int r;
+
+        r = socket_xattr_supported();
+        ASSERT_OK(r);
+
+        log_info("Extended attributes on socket inodes supported: %s", yes_no(r));
+
+        /* A second call must agree with the first. */
+        ASSERT_EQ(socket_xattr_supported(), r);
+}
+
 DEFINE_TEST_MAIN(LOG_DEBUG);