From nobody Thu Mar 19 03:43:12 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5DA2A3101D2; Mon, 16 Feb 2026 13:33:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771248790; cv=none; b=QAPlG5lIME0QL/SIte0hlXVU5JrE6jVMI2XD9NFgCAc86Y+EBpyZII6F4wQeA0zi6LjhVwOmqUbaLNSnfg5i+N8a8HeaAg3QdLTIHfVMLDo7Cz5xg+kJ9Wpps5MtJK0uoOMYJnV2kATJZEi3k/fvjWqJCvm8HKE0neC9sUnl/Fk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1771248790; c=relaxed/simple; bh=hvRp6kqMtP01OL7JzalGLx5e4r/2rC/9MUn7FHvN4XY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=idvFit61RYP1Xyktd7M/h8y5Yj9laNqOtuWK5Ol4s7mtC3fe/qLR+QShb8ezetHdCEiWT1ERIeUK6gdolYgaMcoR0U/JuzvuPjOd/+BCUSYIIdlrRJwc/2FEwcwJrAsBsyUy1SxfGnC0klgz0v7QdTUcpjFU5PwqPaF9IUvJBeE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=ksVRT/TC; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="ksVRT/TC" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 07EADC19423; Mon, 16 Feb 2026 13:33:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1771248790; bh=hvRp6kqMtP01OL7JzalGLx5e4r/2rC/9MUn7FHvN4XY=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=ksVRT/TC3Qs/BDIBZ4Xwz+odoJUU6U4EIeZ15q9gpGsQphl0RvHMnhrcx00O/o44L u8TStq3seKruuRWTCAfpzOHfvucMwPSX/C97ZOFdF4/BgJ2k5CasvzjAlBlIz8PnGE xM/FeirGoDXBN6jq/9WeT3f3VLf/NQ0Pd1cSjE8XARMfC5mF+5PbhiRTClUXTLwL+M Y0hFvkeZF34qG+L0Xjh4pF4S+FZRbyYI0oSk4PwJRBtMWT/ASvV16Mf/NyHc0GNp0V 3GVIfwPUoEmJwb3gr4GnWFSDE/pu+9wKia7m2g/O1iqCXPDbyd8Qe0i+qw3gapxDEA xbK4hkdbLLewQ== From: Christian Brauner Date: Mon, 16 Feb 2026 14:32:10 +0100 Subject: [PATCH 14/14] selftests/xattr: test xattrs on various socket families Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260216-work-xattr-socket-v1-14-c2efa4f74cb7@kernel.org> References: <20260216-work-xattr-socket-v1-0-c2efa4f74cb7@kernel.org> In-Reply-To: <20260216-work-xattr-socket-v1-0-c2efa4f74cb7@kernel.org> To: linux-fsdevel@vger.kernel.org Cc: Jeff Layton , Josef Bacik , Alexander Viro , Jan Kara , linux-kernel@vger.kernel.org, Hugh Dickins , linux-mm@kvack.org, Greg Kroah-Hartman , Tejun Heo , Eric Dumazet , Jakub Kicinski , Jann Horn , netdev@vger.kernel.org, Christian Brauner X-Mailer: b4 0.15-dev-47773 X-Developer-Signature: v=1; a=openpgp-sha256; l=6636; i=brauner@kernel.org; h=from:subject:message-id; bh=hvRp6kqMtP01OL7JzalGLx5e4r/2rC/9MUn7FHvN4XY=; b=owGbwMvMwCU28Zj0gdSKO4sYT6slMWROlokr042WWq769uIti0fds8S7VFz8zzcGv+fTK5kk1 xG/XdC1o5SFQYyLQVZMkcWh3SRcbjlPxWajTA2YOaxMIEMYuDgFYCJCHIwML3UXZu86bHnFwruo 6I2KarM716f/Dv4mfcYbKyuezPq8h+GvdEPpDo5JyQ9slPgXCLvfeSyufcV+SvqkGXd2ZKy1YH/ LCAA= X-Developer-Key: i=brauner@kernel.org; a=openpgp; fpr=4880B8C9BD0E5106FC070F4F7B3C391EFEA93624 Test user.* xattr operations on sockets from different address families: AF_INET, AF_INET6, AF_NETLINK, and AF_PACKET. All socket types use sockfs for their inodes, so user.* xattrs should work regardless of address family. Each fixture creates a socket (no bind needed) and verifies the full fsetxattr/fgetxattr/flistxattr/fremovexattr cycle. AF_INET6 skips if not supported; AF_PACKET skips if CAP_NET_RAW is unavailable. Also tests abstract namespace AF_UNIX sockets, which live in sockfs (not on a filesystem) and should support user.* xattrs. Signed-off-by: Christian Brauner Reviewed-by: Jan Kara --- .../testing/selftests/filesystems/xattr/.gitignore | 1 + tools/testing/selftests/filesystems/xattr/Makefile | 2 +- .../filesystems/xattr/xattr_socket_types_test.c | 177 +++++++++++++++++= ++++ 3 files changed, 179 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/filesystems/xattr/.gitignore b/tools/t= esting/selftests/filesystems/xattr/.gitignore index 00a59c89efab..092d14094c0f 100644 --- a/tools/testing/selftests/filesystems/xattr/.gitignore +++ b/tools/testing/selftests/filesystems/xattr/.gitignore @@ -1,2 +1,3 @@ xattr_socket_test xattr_sockfs_test +xattr_socket_types_test diff --git a/tools/testing/selftests/filesystems/xattr/Makefile b/tools/tes= ting/selftests/filesystems/xattr/Makefile index 2cd722dba47b..95364ffb10e9 100644 --- a/tools/testing/selftests/filesystems/xattr/Makefile +++ b/tools/testing/selftests/filesystems/xattr/Makefile @@ -1,6 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 =20 CFLAGS +=3D $(KHDR_INCLUDES) -TEST_GEN_PROGS :=3D xattr_socket_test xattr_sockfs_test +TEST_GEN_PROGS :=3D xattr_socket_test xattr_sockfs_test xattr_socket_types= _test =20 include ../../lib.mk diff --git a/tools/testing/selftests/filesystems/xattr/xattr_socket_types_t= est.c b/tools/testing/selftests/filesystems/xattr/xattr_socket_types_test.c new file mode 100644 index 000000000000..bfabe91b2ed1 --- /dev/null +++ b/tools/testing/selftests/filesystems/xattr/xattr_socket_types_test.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2026 Christian Brauner +/* + * Test user.* xattrs on various socket families. + * + * All socket types use sockfs for their inodes, so user.* xattrs should + * work on any socket regardless of address family. This tests AF_INET, + * AF_INET6, AF_NETLINK, AF_PACKET, and abstract namespace AF_UNIX sockets. + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../kselftest_harness.h" + +#define TEST_XATTR_NAME "user.testattr" +#define TEST_XATTR_VALUE "testvalue" + +FIXTURE(xattr_socket_types) +{ + int sockfd; +}; + +FIXTURE_VARIANT(xattr_socket_types) +{ + int family; + int type; + int protocol; +}; + +FIXTURE_VARIANT_ADD(xattr_socket_types, inet) { + .family =3D AF_INET, + .type =3D SOCK_STREAM, + .protocol =3D 0, +}; + +FIXTURE_VARIANT_ADD(xattr_socket_types, inet6) { + .family =3D AF_INET6, + .type =3D SOCK_STREAM, + .protocol =3D 0, +}; + +FIXTURE_VARIANT_ADD(xattr_socket_types, netlink) { + .family =3D AF_NETLINK, + .type =3D SOCK_RAW, + .protocol =3D NETLINK_USERSOCK, +}; + +FIXTURE_VARIANT_ADD(xattr_socket_types, packet) { + .family =3D AF_PACKET, + .type =3D SOCK_DGRAM, + .protocol =3D 0, +}; + +FIXTURE_SETUP(xattr_socket_types) +{ + self->sockfd =3D socket(variant->family, variant->type, + variant->protocol); + if (self->sockfd < 0 && + (errno =3D=3D EAFNOSUPPORT || errno =3D=3D EPERM || errno =3D=3D EACC= ES)) + SKIP(return, "socket(%d, %d, %d) not available: %s", + variant->family, variant->type, variant->protocol, + strerror(errno)); + ASSERT_GE(self->sockfd, 0) { + TH_LOG("Failed to create socket(%d, %d, %d): %s", + variant->family, variant->type, variant->protocol, + strerror(errno)); + } +} + +FIXTURE_TEARDOWN(xattr_socket_types) +{ + if (self->sockfd >=3D 0) + close(self->sockfd); +} + +TEST_F(xattr_socket_types, set_get_list_remove) +{ + char buf[256], list[4096], *ptr; + ssize_t ret; + bool found; + + ret =3D fsetxattr(self->sockfd, TEST_XATTR_NAME, + TEST_XATTR_VALUE, strlen(TEST_XATTR_VALUE), 0); + ASSERT_EQ(ret, 0) { + TH_LOG("fsetxattr failed: %s", strerror(errno)); + } + + memset(buf, 0, sizeof(buf)); + ret =3D fgetxattr(self->sockfd, TEST_XATTR_NAME, buf, sizeof(buf)); + ASSERT_EQ(ret, (ssize_t)strlen(TEST_XATTR_VALUE)); + ASSERT_STREQ(buf, TEST_XATTR_VALUE); + + memset(list, 0, sizeof(list)); + ret =3D flistxattr(self->sockfd, list, sizeof(list)); + ASSERT_GT(ret, 0); + found =3D false; + for (ptr =3D list; ptr < list + ret; ptr +=3D strlen(ptr) + 1) { + if (strcmp(ptr, TEST_XATTR_NAME) =3D=3D 0) + found =3D true; + } + ASSERT_TRUE(found); + + ret =3D fremovexattr(self->sockfd, TEST_XATTR_NAME); + ASSERT_EQ(ret, 0); + + ret =3D fgetxattr(self->sockfd, TEST_XATTR_NAME, buf, sizeof(buf)); + ASSERT_EQ(ret, -1); + ASSERT_EQ(errno, ENODATA); +} + +/* + * Test abstract namespace AF_UNIX socket. + * Abstract sockets don't have a filesystem path; their inodes live in + * sockfs so user.* xattrs should work via fsetxattr/fgetxattr. + */ +FIXTURE(xattr_abstract) +{ + int sockfd; +}; + +FIXTURE_SETUP(xattr_abstract) +{ + struct sockaddr_un addr; + char name[64]; + int ret, len; + + self->sockfd =3D socket(AF_UNIX, SOCK_STREAM, 0); + ASSERT_GE(self->sockfd, 0); + + len =3D snprintf(name, sizeof(name), "xattr_test_abstract_%d", getpid()); + + memset(&addr, 0, sizeof(addr)); + addr.sun_family =3D AF_UNIX; + addr.sun_path[0] =3D '\0'; + memcpy(&addr.sun_path[1], name, len); + + ret =3D bind(self->sockfd, (struct sockaddr *)&addr, + offsetof(struct sockaddr_un, sun_path) + 1 + len); + ASSERT_EQ(ret, 0); +} + +FIXTURE_TEARDOWN(xattr_abstract) +{ + if (self->sockfd >=3D 0) + close(self->sockfd); +} + +TEST_F(xattr_abstract, set_get) +{ + char buf[256]; + ssize_t ret; + + ret =3D fsetxattr(self->sockfd, TEST_XATTR_NAME, + TEST_XATTR_VALUE, strlen(TEST_XATTR_VALUE), 0); + ASSERT_EQ(ret, 0) { + TH_LOG("fsetxattr on abstract socket failed: %s", + strerror(errno)); + } + + memset(buf, 0, sizeof(buf)); + ret =3D fgetxattr(self->sockfd, TEST_XATTR_NAME, buf, sizeof(buf)); + ASSERT_EQ(ret, (ssize_t)strlen(TEST_XATTR_VALUE)); + ASSERT_STREQ(buf, TEST_XATTR_VALUE); +} + +TEST_HARNESS_MAIN --=20 2.47.3