From: Stephen Hemminger <stephen@networkplumber.org>
To: netdev@vger.kernel.org
Cc: dsahern@kernel.org, Stephen Hemminger <stephen@networkplumber.org>
Subject: [PATCH iproute2 08/11] ss: read socket SELinux context only for -z
Date: Mon, 9 Nov 2026 13:25:24 -0800 [thread overview]
Message-ID: <20261109212559.39661-9-stephen@networkplumber.org> (raw)
In-Reply-To: <20261109212559.39661-1-stephen@networkplumber.org>
user_ent_hash_build_task() called getfilecon() on /proc/PID/fd/N
for every socket, even without -z, and the path was resolved again
after readlink() had seen a socket. The owner of the descriptor
could swap in a file on a FUSE mount it serves and hang ss -p
in getxattr.
Only look up the context for -z, and read it through an O_PATH
descriptor after checking with readlink(), which does not call into
the file's filesystem, that it is still the same socket.
Reported-by: Anthropic OSS scanner (ANT-2026-EPMKLNM2)
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
misc/ss.c | 35 ++++++++++++++++++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/misc/ss.c b/misc/ss.c
index 74cb3be1..4b3d1fa4 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -533,6 +533,38 @@ static void user_ent_add(unsigned int ino, char *task,
#define MAX_PATH_LEN 1024
+/* The owner of a descriptor can point $PROC_ROOT/$ID/fd/$FD elsewhere
+ * (e.g. at a file on a FUSE mount it serves) after readlink() saw a socket.
+ * Pin the object and check it is still that socket before reading its label.
+ * The check uses readlink(), which does not call into the filesystem of
+ * the pinned object.
+ */
+static int user_ent_sock_context(const char *path, unsigned int ino,
+ char **context)
+{
+ unsigned int pinned;
+ char self[64];
+ char lnk[64];
+ ssize_t len;
+ int ret = -1;
+ int fd;
+
+ fd = open(path, O_PATH | O_CLOEXEC);
+ if (fd < 0)
+ return -1;
+
+ snprintf(self, sizeof(self), "/proc/self/fd/%d", fd);
+ len = readlink(self, lnk, sizeof(lnk) - 1);
+ if (len > 0) {
+ lnk[len] = '\0';
+ if (sscanf(lnk, "socket:[%u]", &pinned) == 1 && pinned == ino)
+ ret = getfilecon(self, context);
+ }
+
+ close(fd);
+ return ret;
+}
+
static void user_ent_hash_build_task(char *path, int pid, int tid)
{
const char *no_ctx = "unavailable";
@@ -580,7 +612,8 @@ static void user_ent_hash_build_task(char *path, int pid, int tid)
if (sscanf(lnk, "socket:[%u]", &ino) != 1)
continue;
- if (getfilecon(path, &sock_context) <= 0)
+ if (!show_sock_ctx ||
+ user_ent_sock_context(path, ino, &sock_context) <= 0)
sock_context = strdup(no_ctx);
if (task[0] == '\0') {
--
2.53.0
next prev parent reply other threads:[~2026-11-09 21:26 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 21:25 [PATCH iproute2 00/11] ss fixes from an OSS scan Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 01/11] ss: fix double close on sock_diag send failure Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 02/11] ss: drop /proc fallback for socket listing Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 03/11] ss: escape names chosen by the socket owner Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 04/11] ss: size the TCPDIAG_FILE buffer to the record Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 05/11] ss: replay all dumps in TCPDIAG_FILE Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 06/11] ss: bound state and type name lookups Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 07/11] ss: fix rpcbind service cache Stephen Hemminger
2026-11-09 21:25 ` Stephen Hemminger [this message]
2026-11-09 21:25 ` [PATCH iproute2 09/11] ss: check owner before naming a netlink socket Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 10/11] ss: keep following events after ENOBUFS Stephen Hemminger
2026-11-09 21:25 ` [PATCH iproute2 11/11] ss: report a failed SCTP or MPTCP dump Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261109212559.39661-9-stephen@networkplumber.org \
--to=stephen@networkplumber.org \
--cc=dsahern@kernel.org \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox