From: Lennart Poettering Date: Wed, 3 Jun 2026 09:06:23 +0000 (+0200) Subject: socket-util: add new helper socket_xattr_supported() X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f304250315f8f282dffbe22e57ae3e086bfb99e7;p=thirdparty%2Fsystemd.git socket-util: add new helper socket_xattr_supported() --- diff --git a/TODO.md b/TODO.md index 1ebad3fcf84..4d6668dace7 100644 --- 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:** diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index d8f41f0f9c0..c25e41d7719 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #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); +} diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index b3a2733b74a..f9d6ddaaad0 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -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); diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 713844b09b7..038140d4c57 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #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);