unix.7: Socket Options and SCM_* fixes
cover unix.7: Socket Options and SCM_* fixes
Hello!
This is patch set (B) spun off from the "Documentation fixes in unix(7)" patch set [1], which is now split into these three parts:
(A) Miscellaneous fixes, mostly in unix.7, one in socket.7
(B) Socket options and Socket-level Control Messages (SCM_*) <-- this one
(C) sock_diag.7
This patch set fixes unix(7) documentation related to socket options and SCM_* control messages. The first 5 commits are fixes and factual corrections, the last two commits are documenting two relevant new features (PIDFD passing and SO_PASSRIGHTS).
The patch set is based on the "miscellaneous" patch set (A) ("General Unix Domain Socket fixes"), since it is touching some error code documentation in the same corner as what is getting changed in (A).
Thank you for your reviews on v1 and v2 of the still-joined patch set. Compared to v2, the following things happened:
* Some commit message rewording (especially quoted the kernel code more directly).
* I removed the commit that changed the wording about Out-of-Band messaging, per Kuniyuki's suggestion in [2].
* The ETOOMANYREFS commit is a SCM_RIGHTS-specific error; the Autobind documentation change is included here because it refers to SO_PASSPIDFD.
* I am not 100% happy with how verbose the SCM_SECURITY change has become, but I don't see a good way to shorten it without cutting away from the substance.
More details are attached in the commit notes.
This patch set has been produced with the help of a LLM, which was helpful for spotting a long list of inaccuracies, comparing the documentation with the kernel implementation. (More details in [1])
–Günther
P.S.: Part (C) will come soon, but not today any more. :)
That part is more independent again and, being about "sock_diag", it is outside of the main unix(7) documentation.
[1] https://lore.kernel.org/all/[email protected]/
[2] https://lore.kernel.org/all/CAAVpQUBh+J-aBLbkpzT7qmt7B714O529HWcTuQsVLT4wLBnDJA@mail.gmail.com/
Günther Noack (7):
man/man7/unix.7: ERRORS: ETOOMANYREFS: Fix the conditions man/man7/unix.7: Multiple same-typed SCM_* messages may be sent in one
message
man/man7/unix.7: Autobind: Clarify when it happens, and mention
SO_PASSPIDFD
man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just
SELinux
man/man7/unix.7: SO_PASSSEC: wfix
man/man7/unix.7: Document SO_PASSPIDFD, SO_PEERPIDFD, and SCM_PIDFD man/man7/unix.7: Document SO_PASSRIGHTS
man/man7/unix.7 | 215 ++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 201 insertions(+), 14 deletions(-)
Signature · 1 line
2.56.0
PATCH 1/7 man/man7/unix.7: ERRORS: ETOOMANYREFS: Fix the conditions
The ETOOMANYREFS error is detected in too_many_unix_fds() in net/unix/af_unix.c when the user's (not the processes') in-flight FDs exceed RLIMIT_NOFILE, and the process has neither CAP_SYS_RESOURCE nor CAP_SYS_ADMIN. The error is raised when all of the following (simplified) conditions are true:
* user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)
* !capable(CAP_SYS_RESOURCE)
* !capable(CAP_SYS_ADMIN)
The check was introduced in linux.git 712f4aad406b (2016-01-11; "unix:
properly account for FDs passed over unix sockets").
---
Notes:
Double checked in code -- the condition under which this error is returned was not fully spelled out.
man/man7/unix.7 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
man/man7/unix.7 +6 -2
@@ -785,10 +785,14 @@ when sending a file descriptor as ancillary data over a UNIX domain socket (see the description of .BR SCM_RIGHTS , above). -It occurs if the number of "in-flight" file descriptors exceeds the +It occurs if the number of "in-flight" file descriptors +sent by processes of the caller's real user ID +exceeds the caller's .B RLIMIT_NOFILE -resource limit and the caller does not have the +resource limit and the caller has neither the .B CAP_SYS_RESOURCE +nor the +.B CAP_SYS_ADMIN capability. An in-flight file descriptor is one that has been sent using .BR sendmsg (2)
Signature · 1 line
2.56.0
Re: [PATCH 1/7] man/man7/unix.7: ERRORS: ETOOMANYREFS: Fix the conditions
Hi Günther
Quoted 16 lines
Date: 2026-10-21 23:22:50+0200
From: Günther Noack <[email protected]>The ETOOMANYREFS error is detected in
too_many_unix_fds()innet/unix/af_unix.cwhen the user's (not the processes') in-flight FDs exceedRLIMIT_NOFILE, and the process has neitherCAP_SYS_RESOURCEnorCAP_SYS_ADMIN. The error is raised when all of the following (simplified) conditions are true:*
user->unix_inflight>task_rlimit(p, RLIMIT_NOFILE)
* !capable(CAP_SYS_RESOURCE)
* !capable(CAP_SYS_ADMIN)The check was introduced in linux.git
712f4aad406b(2016-01-11; "unix:
properly account for FDs passed over unix sockets").
Quoted 7 lines
Fixes dc4eea68b565 (2016-12-17; "unix.7: Document ETOOMANYREFS for SCM_RIGHTS send exceeding RLIMIT_NOFILE limit")Cc Michael Kerrisk <[email protected]>Cc Willy Tarreau <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
man/man7/unix.7 when sending a file descriptor as ancillary data over
Quoted 13 lines
Notes:
Double checked in code -- the condition under which this error is returned was not fully spelled out.man/man7/unix.7 | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)man/man7/unix.7 +0
-0@@ -785,10 +785,14 @@ when sending a file descriptor as ancillary data over
Would you mind having a look at CONTRIBUTING.d/git for improving the hunk context?
git-diff(1), gitattributes(5) To produce useful hunk contexts in manual pages, we need to hack git(1)'s idea of a function name, and also to tell git what is a manual page. $ git config --global diff.man.xfuncname '^\.S[SHsh] .*$'; $ mkdir -p ~/.config/git/; $ echo '*.[0-9]* diff=man' >>~/.config/git/attributes;
Cheers,
Alex
Quoted 20 lines
man/man7/unix.7 +6
-2a UNIX domain socket (see the description of .BR SCM_RIGHTS , above). -It occurs if the number of "in-flight" file descriptors exceeds the +It occurs if the number of "in-flight" file descriptors +sent by processes of the caller's real user ID +exceeds the caller's .B RLIMIT_NOFILE -resource limit and the caller does not have the +resource limit and the caller has neither the .B CAP_SYS_RESOURCE +nor the +.B CAP_SYS_ADMIN capability. An in-flight file descriptor is one that has been sent using .BR sendmsg (2)Signature · 1 line
2.56.0
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 1/7] man/man7/unix.7: ERRORS: ETOOMANYREFS: Fix the conditions
Quoted 9 lines · Alejandro Colomar
man/man7/unix.7 when sending a file descriptor as ancillary data over
Quoted 5 lines
man/man7/unix.7 +0
-0@@ -785,10 +785,14 @@ when sending a file descriptor as ancillary data overWould you mind having a look at CONTRIBUTING.d/git for improving the hunk context?
Quoted 8 lines
git-diff(1), gitattributes(5) To produce useful hunk contexts in manual pages, we need to hack git(1)'s idea of a function name, and also to tell git what is a manual page. $ git config --global diff.man.xfuncname '^\.S[SHsh] .*$'; $ mkdir -p ~/.config/git/; $ echo '*.[0-9]* diff=man' >>~/.config/git/attributes;
Nice trick! Applied.
–Günther
Re: [PATCH 1/7] man/man7/unix.7: ERRORS: ETOOMANYREFS: Fix the conditions
In reply to Günther NoackQuoted 13 lines · Günther Noack
The ETOOMANYREFS error is detected in
too_many_unix_fds()innet/unix/af_unix.cwhen the user's (not the processes') in-flight FDs exceedRLIMIT_NOFILE, and the process has neitherCAP_SYS_RESOURCEnorCAP_SYS_ADMIN. The error is raised when all of the following (simplified) conditions are true:*
user->unix_inflight>task_rlimit(p, RLIMIT_NOFILE)
* !capable(CAP_SYS_RESOURCE)
* !capable(CAP_SYS_ADMIN)The check was introduced in linux.git
712f4aad406b(2016-01-11; "unix:
properly account for FDs passed over unix sockets").
Quoted 6 lines
Fixes dc4eea68b565 (2016-12-17; "unix.7: Document ETOOMANYREFS for SCM_RIGHTS send exceeding RLIMIT_NOFILE limit")Cc Michael Kerrisk <[email protected]>Cc Willy Tarreau <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>
PATCH 2/7 man/man7/unix.7: Multiple same-typed SCM_* messages may be sent in one message
In reply to Günther NoackVerified in Linux kernel code:
__scm_send() in linux.git net/core/scm.c walks all control messages in a loop like this:
for_each_cmsghdr(cmsg, msg) {
// ...
switch (cmsg->cmsg_type)
{
case SCM_RIGHTS:
// Append(!) file descriptors
// up to the SCM_MAX_FD limit
break;
case SCM_CREDENTIALS:
// Replace previously set credentials
break;
default:
goto error;
}
}So it is possible to pass multiple SCM_* messages -- they will compose if possible and override the previous value if not. Since their contents are being conflated that way, they will appear as one message again on the receiving side.
Keep the recommendation as portability advice, and describe the Linux behavior.
---
Notes:
The factual analysis in the commit message is correct.
I kept the LLM phrasing; it did not seem overly wordy to me and the style is in line with the paragraph after it, which also documents Linux-only vs. portable APIs that way.
man/man7/unix.7 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
man/man7/unix.7 +18 -1
@@ -543,7 +543,24 @@ option must be enabled on the socket (see above). .P When sending ancillary data with .BR sendmsg (2), -only one item of each of the above types may be included in the sent message. +portable applications should include +only one item of each of the above types in the sent message. +On Linux, +if several +.B SCM_RIGHTS +items are included, +their file descriptors are combined into a single list, +to which the +.B SCM_MAX_FD +limit applies as a whole, +and the receiver gets them in a single +.B SCM_RIGHTS +item; +if several +.B SCM_CREDENTIALS +items are included, +each of them is checked, +and the last one takes effect. .P At least one byte of real data should be sent when sending ancillary data. On Linux, this is required to successfully send ancillary data over
Signature · 1 line
2.56.0
Alejandro Colomar
maintainerRe: [PATCH 2/7] man/man7/unix.7: Multiple same-typed SCM_* messages may be sent in one message
Hi Günther,
Quoted 4 lines
Date: 2026-10-21 23:22:51+0200
From: Günther Noack <[email protected]>Verified in Linux kernel code:
I think 'verified' in a commit message seems inappropriate. It should describe, rather than verify, and the verification would come only from the review tags. Maybe say something like "Relevant kernel code:".
Quoted 13 lines
__scm_send()in linux.gitnet/core/scm.cwalks all control messages in a loop like this:for_each_cmsghdr(cmsg, msg) { // ... switch (cmsg->cmsg_type) { case SCM_RIGHTS: // Append(!) file descriptors // up to the SCM_MAX_FD limit break; case SCM_CREDENTIALS: // Replace previously set credentials
Since these are your comments, and not actual comments in the source code (are they yours, or from the LLM?), I'd format them clearly as such using invalid code rather than comments:
... replace previously set credentials ...
Quoted 48 lines
break; default: goto error; } }So it is possible to pass multiple SCM_* messages -- they will compose if possible and override the previous value if not. Since their contents are being conflated that way, they will appear as one message again on the receiving side.
Keep the recommendation as portability advice, and describe the Linux behavior.
Fixes 5b5cb1958062 (2018-07-10; "unix.7: When sending ancillary data, only one item of each type may be sent")Cc Michael Kerrisk <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
The factual analysis in the commit message is correct.I kept the LLM phrasing; it did not seem overly wordy to me and the style is in line with the paragraph after it, which also documents Linux-only vs. portable APIs that way.
man/man7/unix.7 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)man/man7/unix.7 +8
-1@@ -543,7 +543,24 @@ option must be enabled on the socket (see above). .P When sending ancillary data with .BR sendmsg (2), -only one item of each of the above types may be included in the sent message. +portable applications should include +only one item of each of the above types in the sent message. +On Linux, +if several +.B SCM_RIGHTS +items are included, +their file descriptors are combined into a single list, +to which the
man/man7/unix.7 option must be enabled on the socket (see above). · line 563
Quoted 10 lines
man/man7/unix.7 +10
-0+.B SCM_MAX_FD +limit applies as a whole, +and the receiver gets them in a single +.B SCM_RIGHTS +item; +if several +.B SCM_CREDENTIALS +items are included, +each of them is checked, +and the last one takes effect.
Is 'takes effect' appropriate? I think 'is sent' might be more appropriate, right? There's nothing taking effect, I think (but I'm not an expert in SCM_* stuff).
Have a lovely night!
Alex
Quoted 6 lines
man/man7/unix.7 +0
-0.P At least one byte of real data should be sent when sending ancillary data. On Linux, this is required to successfully send ancillary data overSignature · 1 line
2.56.0
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 2/7] man/man7/unix.7: Multiple same-typed SCM_* messages may be sent in one message
Hello Alejandro!
Quoted 8 lines · Alejandro Colomar
Quoted 4 lines
Date: 2026-10-21 23:22:51+0200
From: Günther Noack <[email protected]>Verified in Linux kernel code:
I think 'verified' in a commit message seems inappropriate. It should describe, rather than verify, and the verification would come only from the review tags. Maybe say something like "Relevant kernel code:".
Good point, replaced. I'll double check the other commits as well.
Quoted 14 lines
Quoted 13 lines
__scm_send()in linux.gitnet/core/scm.cwalks all control messages in a loop like this:for_each_cmsghdr(cmsg, msg) { // ... switch (cmsg->cmsg_type) { case SCM_RIGHTS: // Append(!) file descriptors // up to the SCM_MAX_FD limit break; case SCM_CREDENTIALS: // Replace previously set credentials
Quoted 5 lines
Since these are your comments, and not actual comments in the source code (are they yours, or from the LLM?), I'd format them clearly as such using invalid code rather than comments:
... replace previously set credentials ...
Done.
Yes, I transcribed the source code by hand here, including these comments.
Quoted 54 lines
Quoted 54 lines
break; default: goto error; } }So it is possible to pass multiple SCM_* messages -- they will compose if possible and override the previous value if not. Since their contents are being conflated that way, they will appear as one message again on the receiving side.
Keep the recommendation as portability advice, and describe the Linux behavior.
Fixes 5b5cb1958062 (2018-07-10; "unix.7: When sending ancillary data, only one item of each type may be sent")Cc Michael Kerrisk <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
The factual analysis in the commit message is correct.I kept the LLM phrasing; it did not seem overly wordy to me and the style is in line with the paragraph after it, which also documents Linux-only vs. portable APIs that way.
man/man7/unix.7 | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)man/man7/unix.7 +14
-1@@ -543,7 +543,24 @@ option must be enabled on the socket (see above). .P When sending ancillary data with .BR sendmsg (2), -only one item of each of the above types may be included in the sent message. +portable applications should include +only one item of each of the above types in the sent message. +On Linux, +if several +.B SCM_RIGHTS +items are included, +their file descriptors are combined into a single list, +to which the +.B SCM_MAX_FD +limit applies as a whole, +and the receiver gets them in a single +.B SCM_RIGHTS +item; +if several
Quoted 8 lines
man/man7/unix.7 option must be enabled on the socket (see above). · line 563
Quoted 4 lines
man/man7/unix.7 +4
-0+.B SCM_CREDENTIALS +items are included, +each of them is checked, +and the last one takes effect.Is 'takes effect' appropriate? I think 'is sent' might be more appropriate, right? There's nothing taking effect, I think (but I'm not an expert in SCM_* stuff).
You are right, "takes effect" is maybe too much described from the angle of the implementation - I replaced it with "is sent".
What's happening is that the sender process specifies the "struct ucred", which contains a pid, uid and gid in the SCM_CREDENTIALS control message. When the kernel deals with these, it *checks* that they are valid (they describe the sending process *OR* the sending process is privileged and can send what it wants). Only the last of these SCM_CREDENTIALS messages survives that processing though and the receiving process then only sees that last one.
Thanks for the review!
–Günther
PATCH 3/7 man/man7/unix.7: Autobind: Clarify when it happens, and mention SO_PASSPIDFD
In reply to Günther NoackAutobind happens if either one of SO_PASSCRED/SO_PASSPIDFD is set and either connect() or sendmsg() happens. Mention SO_PASSPIDFD and clarify that autobind does not happen immediately when setting these socket options.
In linux.git net/unix/af_unix.c, unix_autobind() is called by unix_dgram_connect(), unix_stream_connect() and unix_dgram_sendmsg(), if the socket has no address and unix_may_passcred() is true.
unix_may_passcred() is also true when SO_PASSPIDFD is set, which was added in linux.git 5e2ff6704a27 (2023-06-12; "scm: add SO_PASSPIDFD and SCM_PIDFD"), Linux 6.5.
Also, the old text said "not yet connected", but the condition is about the socket not being bound.
---
Notes:
Rephrased the LLM-generated text so that the canonical description is in the "Autobind feature" section and the other place just refers to it.
SO_PASSPIDFD is unfortunately not documented yet at this point in time, but it's still correct to mention it here.
man/man7/unix.7 | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)
man/man7/unix.7 +20 -5
@@ -301,8 +301,14 @@ if the sender did not specify .B SCM_CREDENTIALS ancillary data. .IP -When this option is set and the socket is not yet connected, -a unique name in the abstract namespace will be generated automatically. +When this option is set on a socket that is not bound to an address, +the socket is autobound to a unique name in the abstract namespace +when +.BR connect (2) +or +.BR sendmsg (2) +is called on it; +see "Autobind feature", below. .IP The value given as an argument to .BR setsockopt (2)
@@ -370,10 +376,19 @@ call specifies as .IR sizeof(sa_family_t) , .\" i.e., sizeof(short) -or the +or if +.BR connect (2) +or +.BR sendmsg (2) +is called on a socket that was +not explicitly bound to an address +and that has the .B SO_PASSCRED -socket option was specified for a socket that was -not explicitly bound to an address, +or +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89 +.B SO_PASSPIDFD +(since Linux 6.5) +socket option enabled, then the socket is autobound to an abstract address. The address consists of a null byte followed by 5 bytes in the character set
Signature · 1 line
2.56.0
Re: [PATCH 3/7] man/man7/unix.7: Autobind: Clarify when it happens, and mention SO_PASSPIDFD
Quoted 64 lines · Günther Noack
Autobind happens if either one of SO_PASSCRED/SO_PASSPIDFD is set and either
connect()orsendmsg()happens. MentionSO_PASSPIDFDand clarify that autobind does not happen immediately when setting these socket options.In linux.git
net/unix/af_unix.c,unix_autobind()is called byunix_dgram_connect(),unix_stream_connect()andunix_dgram_sendmsg(), if the socket has no address andunix_may_passcred()is true.
unix_may_passcred()is also true whenSO_PASSPIDFDis set, which was added in linux.git5e2ff6704a27(2023-06-12; "scm: addSO_PASSPIDFDandSCM_PIDFD"), Linux 6.5.Also, the old text said "not yet connected", but the condition is about the socket not being bound.
Fixes 9d1fd1157306 (1999-06-15, 2022-12-19; "man-pages 1.24")Fixes 0cf2caa41ea6 (2010-10-10; "unix.7: Document the autobind feature")Cc Michael Kerrisk <[email protected]>Cc Alexander Mikhalitsyn <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
Rephrased the LLM-generated text so that the canonical description is in the "Autobind feature" section and the other place just refers to it.
SO_PASSPIDFDis unfortunately not documented yet at this point in time, but it's still correct to mention it here.man/man7/unix.7 | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)man/man7/unix.7 +10
-3@@ -301,8 +301,14 @@ if the sender did not specify .B SCM_CREDENTIALS ancillary data. .IP -When this option is set and the socket is not yet connected, -a unique name in the abstract namespace will be generated automatically. +When this option is set on a socket that is not bound to an address, +the socket is autobound to a unique name in the abstract namespace +when +.BR connect (2) +or +.BR sendmsg (2) +is called on it; +see "Autobind feature", below. .IP The value given as an argument to .BR setsockopt (2)@@ -370,10 +376,19 @@ call specifies as .IR sizeof(sa_family_t) , .\" i.e., sizeof(short) -or the +or if +.BR connect (2)
man/man7/unix.7 call specifies · line 388
Quoted 10 lines
man/man7/unix.7 +7
-2+or +.BR sendmsg (2) +is called on a socket that was +not explicitly bound to an address +and that has the .B SO_PASSCRED -socket option was specified for a socket that was -not explicitly bound to an address, +or +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89
Do we really need this SHA1 here ?
man/man7/unix.7 call specifies · line 391
Quoted 3 lines
man/man7/unix.7 +3
-0+.B SO_PASSPIDFD +(since Linux 6.5) +socket option enabled,
You will need to update here with SO_PASSPIDFD_THREAD,
https://lore.kernel.org/netdev/[email protected]/
but I'm not sure to what extent you want to clarify things.
For example, is "the socket is autobound when it passes credentials or pidfd but is not yet bound." too vague ?
Quoted 6 lines
man/man7/unix.7 +0
-0then the socket is autobound to an abstract address. The address consists of a null byte followed by 5 bytes in the character setSignature · 1 line
2.56.0
Re: [PATCH 3/7] man/man7/unix.7: Autobind: Clarify when it happens, and mention SO_PASSPIDFD
Quoted 69 lines · Kuniyuki Iwashima
Quoted 68 lines · Günther Noack
Autobind happens if either one of SO_PASSCRED/SO_PASSPIDFD is set and either
connect()orsendmsg()happens. MentionSO_PASSPIDFDand clarify that autobind does not happen immediately when setting these socket options.In linux.git
net/unix/af_unix.c,unix_autobind()is called byunix_dgram_connect(),unix_stream_connect()andunix_dgram_sendmsg(), if the socket has no address andunix_may_passcred()is true.
unix_may_passcred()is also true whenSO_PASSPIDFDis set, which was added in linux.git5e2ff6704a27(2023-06-12; "scm: addSO_PASSPIDFDandSCM_PIDFD"), Linux 6.5.Also, the old text said "not yet connected", but the condition is about the socket not being bound.
Fixes 9d1fd1157306 (1999-06-15, 2022-12-19; "man-pages 1.24")Fixes 0cf2caa41ea6 (2010-10-10; "unix.7: Document the autobind feature")Cc Michael Kerrisk <[email protected]>Cc Alexander Mikhalitsyn <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
Rephrased the LLM-generated text so that the canonical description is in the "Autobind feature" section and the other place just refers to it.
SO_PASSPIDFDis unfortunately not documented yet at this point in time, but it's still correct to mention it here.man/man7/unix.7 | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)man/man7/unix.7 +14
-3@@ -301,8 +301,14 @@ if the sender did not specify .B SCM_CREDENTIALS ancillary data. .IP -When this option is set and the socket is not yet connected, -a unique name in the abstract namespace will be generated automatically. +When this option is set on a socket that is not bound to an address, +the socket is autobound to a unique name in the abstract namespace +when +.BR connect (2) +or +.BR sendmsg (2) +is called on it; +see "Autobind feature", below. .IP The value given as an argument to .BR setsockopt (2)@@ -370,10 +376,19 @@ call specifies as .IR sizeof(sa_family_t) , .\" i.e., sizeof(short) -or the +or if +.BR connect (2) +or +.BR sendmsg (2) +is called on a socket that was +not explicitly bound to an address
Quoted 8 lines
man/man7/unix.7 call specifies · line 388
Quoted 6 lines
man/man7/unix.7 +3
-2+and that has the .B SO_PASSCRED -socket option was specified for a socket that was -not explicitly bound to an address, +or +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89Do we really need this SHA1 here ?
I'll drop it, since it's already pointed out in the commit message. It seemed like the convention in these man pages, but apparently it's not needed any more, as Alejandro also remarked in [1].
[1] https://lore.kernel.org/all/atulJkR7fAgyKhPP@debian/
Quoted 6 lines
man/man7/unix.7 call specifies · line 391
Quoted 3 lines
man/man7/unix.7 +3
-0+.B SO_PASSPIDFD +(since Linux 6.5) +socket option enabled,You will need to update here with
SO_PASSPIDFD_THREAD,
https://lore.kernel.org/netdev/[email protected]/
SO_PASSPIDFD_THREAD did not make it into Linux 7.3, and man pages document stable features only, so it will have to go separately at a later point in time.
Quoted 4 lines
but I'm not sure to what extent you want to clarify things.
For example, is "the socket is autobound when it passes credentials or pidfd but is not yet bound." too vague ?
In my ears, "passing credentials" might as well mean that the current credentials are being *sent* over the socket, rather than received. We could maybe say "when it is configured to receive credentials or pidfd"? (But at that point, it's similarly long and less precise than just listing the socket options.) I'd keep it as is for now, if that's OK.
–Günther
Re: [PATCH 3/7] man/man7/unix.7: Autobind: Clarify when it happens, and mention SO_PASSPIDFD
Quoted 103 lines · Günther Noack
Quoted 69 lines · Kuniyuki Iwashima
Quoted 68 lines · Günther Noack
Autobind happens if either one of SO_PASSCRED/SO_PASSPIDFD is set and either
connect()orsendmsg()happens. MentionSO_PASSPIDFDand clarify that autobind does not happen immediately when setting these socket options.In linux.git
net/unix/af_unix.c,unix_autobind()is called byunix_dgram_connect(),unix_stream_connect()andunix_dgram_sendmsg(), if the socket has no address andunix_may_passcred()is true.
unix_may_passcred()is also true whenSO_PASSPIDFDis set, which was added in linux.git5e2ff6704a27(2023-06-12; "scm: addSO_PASSPIDFDandSCM_PIDFD"), Linux 6.5.Also, the old text said "not yet connected", but the condition is about the socket not being bound.
Fixes 9d1fd1157306 (1999-06-15, 2022-12-19; "man-pages 1.24")Fixes 0cf2caa41ea6 (2010-10-10; "unix.7: Document the autobind feature")Cc Michael Kerrisk <[email protected]>Cc Alexander Mikhalitsyn <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
Rephrased the LLM-generated text so that the canonical description is in the "Autobind feature" section and the other place just refers to it.
SO_PASSPIDFDis unfortunately not documented yet at this point in time, but it's still correct to mention it here.man/man7/unix.7 | 25 ++++++++++++++++++++----- 1 file changed, 20 insertions(+), 5 deletions(-)man/man7/unix.7 +14
-3@@ -301,8 +301,14 @@ if the sender did not specify .B SCM_CREDENTIALS ancillary data. .IP -When this option is set and the socket is not yet connected, -a unique name in the abstract namespace will be generated automatically. +When this option is set on a socket that is not bound to an address, +the socket is autobound to a unique name in the abstract namespace +when +.BR connect (2) +or +.BR sendmsg (2) +is called on it; +see "Autobind feature", below. .IP The value given as an argument to .BR setsockopt (2)@@ -370,10 +376,19 @@ call specifies as .IR sizeof(sa_family_t) , .\" i.e., sizeof(short) -or the +or if +.BR connect (2) +or +.BR sendmsg (2) +is called on a socket that was +not explicitly bound to an addressQuoted 8 lines
man/man7/unix.7 call specifies · line 388
Quoted 6 lines
man/man7/unix.7 +3
-2+and that has the .B SO_PASSCRED -socket option was specified for a socket that was -not explicitly bound to an address, +or +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89Do we really need this SHA1 here ?
I'll drop it, since it's already pointed out in the commit message. It seemed like the convention in these man pages, but apparently it's not needed any more, as Alejandro also remarked in [1].
[1] https://lore.kernel.org/all/atulJkR7fAgyKhPP@debian/
Quoted 6 lines
man/man7/unix.7 call specifies · line 391
Quoted 3 lines
man/man7/unix.7 +3
-0+.B SO_PASSPIDFD +(since Linux 6.5) +socket option enabled,You will need to update here with
SO_PASSPIDFD_THREAD,
https://lore.kernel.org/netdev/[email protected]/
SO_PASSPIDFD_THREADdid not make it into Linux 7.3, and man pages document stable features only, so it will have to go separately at a later point in time.Quoted 4 lines
but I'm not sure to what extent you want to clarify things.
For example, is "the socket is autobound when it passes credentials or pidfd but is not yet bound." too vague ?
Quoted 6 lines
In my ears, "passing credentials" might as well mean that the current credentials are being *sent* over the socket, rather than received. We could maybe say "when it is configured to receive credentials or pidfd"? (But at that point, it's similarly long and less precise than just listing the socket options.) I'd keep it as is for now, if that's OK.
Fair enough :)
PATCH 4/7 man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
In reply to Günther NoackReword the description of SCM_SECURITY to not be specific to SELinux.
The security context is populated in scm_passec() in linux.git net/core/scm.c, through the security_secid_to_secctx() LSM hook, which is currently implemented by SELinux, Smack and AppArmor.
Also clarify the properties of the returned string:
* There is no NAME_MAX limit on the length; SELinux contexts can be longer than that. If the control buffer is too small, put_cmsg() truncates the data and sets MSG_CTRUNC.
* Whether the string is null-terminated also depends on the LSM:
SELinux includes the null byte in the length, but smack_to_secctx() in security/smack/smack_lsm.c uses strlen() and doesn't.
---
Notes:
This feature is also available in other LSMs. Unfortunately, they implemented it inconsistently and that complicates the description of how string boundaries are handled. Linux does indeed neither guarantee that this terminates with a NUL byte, nor that NAME_MAX is large enough to hold it.
This is the verbose variant, but I am open for suggestions regarding what level of detail is appropriate here.
man/man7/unix.7 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)
man/man7/unix.7 +19 -6
@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the SELinux security label of the peer socket +Enables receiving of the security label of the peer socket in an ancillary message of type .B SCM_SECURITY (see below).
@@ -544,13 +544,26 @@ message, the option must be enabled on the socket. .TP .B SCM_SECURITY -Receive the SELinux security context (the security label) -of the peer socket. -The received ancillary data is a null-terminated string containing +Receive the security context (the security label) +of the peer socket, +as provided by the active Linux Security Module (LSM), +such as SELinux or Smack. +The received ancillary data is a string containing the security context. -The receiver should allocate at least +Whether the string includes a terminating null byte +depends on the LSM; +the length of the data is given by the +.I cmsg_len +field. +There is no fixed limit on the length of the security context; +allocating .B NAME_MAX -bytes in the data portion of the ancillary message for this data. +bytes in the data portion of the ancillary message +is usually enough. +If the buffer is too small, +the data is truncated and the +.B MSG_CTRUNC +flag is set (see below). .IP To receive the security context, the .B SO_PASSSEC
Signature · 1 line
2.56.0
Alejandro Colomar
maintainerRe: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hi Günther,
Quoted 18 lines
Date: 2026-10-21 23:22:53+0200
From: Günther Noack <[email protected]>Reword the description of
SCM_SECURITYto not be specific to SELinux.The security context is populated in
scm_passec()in linux.gitnet/core/scm.c, through thesecurity_secid_to_secctx()LSM hook, which is currently implemented by SELinux, Smack and AppArmor.Also clarify the properties of the returned string:
* There is no
NAME_MAXlimit on the length; SELinux contexts can be longer than that. If the control buffer is too small,put_cmsg()truncates the data and setsMSG_CTRUNC.* Whether the string is null-terminated also depends on the LSM:
SELinux includes the null byte in the length, butsmack_to_secctx()insecurity/smack/smack_lsm.cusesstrlen()and doesn't.
...
Quoted 13 lines
Fixes ffad6a017f91 (2018-07-28; "unix.7: Document SCM_SECURITY ancillary data")Cc Michael Kerrisk <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
This feature is also available in other LSMs. Unfortunately, they implemented it inconsistently and that complicates the description of how string boundaries are handled. Linux does indeed neither guarantee that this terminates with a NUL byte, nor thatNAME_MAXis large enough to hold it.
...
Quoted 26 lines
This is the verbose variant, but I am open for suggestions regarding what level of detail is appropriate here.
man/man7/unix.7 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)man/man7/unix.7 +1
-3@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the SELinux security label of the peer socket +Enables receiving of the security label of the peer socket in an ancillary message of type .B SCM_SECURITY (see below).@@ -544,13 +544,26 @@ message, the option must be enabled on the socket. .TP .B SCM_SECURITY -Receive the SELinux security context (the security label) -of the peer socket.
man/man7/unix.7 message, the · line 554
Quoted 10 lines
man/man7/unix.7 +7
-2-The received ancillary data is a null-terminated string containing +Receive the security context (the security label) +of the peer socket, +as provided by the active Linux Security Module (LSM), +such as SELinux or Smack. +The received ancillary data is a string containing the security context. -The receiver should allocate at least +Whether the string includes a terminating null byte +depends on the LSM;
This seems to contradict the commit message. The commit message says that the string is terminated, but that the reported length might or might not be off-by-one (i.e., not count or count the '\0').
This text, however, is saying that in some cases there might not be a '\0' at all.
Am I missing something?
Have a lovely day!
Alex
Quoted 20 lines
man/man7/unix.7 +11
-1+the length of the data is given by the +.I cmsg_len +field. +There is no fixed limit on the length of the security context; +allocating .B NAME_MAX -bytes in the data portion of the ancillary message for this data. +bytes in the data portion of the ancillary message +is usually enough. +If the buffer is too small, +the data is truncated and the +.B MSG_CTRUNC +flag is set (see below). .IP To receive the security context, the .B SO_PASSSECSignature · 1 line
2.56.0
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hello Alejandro!
Quoted 15 lines · Alejandro Colomar
Quoted 15 lines
Date: 2026-10-21 23:22:53+0200
From: Günther Noack <[email protected]>Reword the description of
SCM_SECURITYto not be specific to SELinux.The security context is populated in
scm_passec()in linux.gitnet/core/scm.c, through thesecurity_secid_to_secctx()LSM hook, which is currently implemented by SELinux, Smack and AppArmor.Also clarify the properties of the returned string:
* There is no
NAME_MAXlimit on the length; SELinux contexts can be longer than that. If the control buffer is too small,put_cmsg()truncates the data and setsMSG_CTRUNC.
Quoted 5 lines
Quoted 3 lines
* Whether the string is null-terminated also depends on the LSM:
SELinux includes the null byte in the length, butsmack_to_secctx()insecurity/smack/smack_lsm.cusesstrlen()and doesn't....
Ah, I can see that this is confusing; let me reformulate that without mentioning this strlen() implementation detail. Smack returns a buffer with a given size *without* including the null byte, roughly like this (simplified):
int len = strlen(skp->smk_known); /* populate */ cp->context = skp->smk_known; cp->len = len; <-- does not span the null byte
Reformulating to:
...but smack_to_secctx() in security/smack/smack_lsm.c sends a security context that does not end in a null byte.
Quoted 57 lines
Quoted 13 lines
Fixes ffad6a017f91 (2018-07-28; "unix.7: Document SCM_SECURITY ancillary data")Cc Michael Kerrisk <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
This feature is also available in other LSMs. Unfortunately, they implemented it inconsistently and that complicates the description of how string boundaries are handled. Linux does indeed neither guarantee that this terminates with a NUL byte, nor thatNAME_MAXis large enough to hold it....
Quoted 26 lines
This is the verbose variant, but I am open for suggestions regarding what level of detail is appropriate here.
man/man7/unix.7 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)man/man7/unix.7 +1
-3@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the SELinux security label of the peer socket +Enables receiving of the security label of the peer socket in an ancillary message of type .B SCM_SECURITY (see below).@@ -544,13 +544,26 @@ message, the option must be enabled on the socket. .TP .B SCM_SECURITY -Receive the SELinux security context (the security label) -of the peer socket.man/man7/unix.7 message, the · line 554
Quoted 10 lines
man/man7/unix.7 +7
-2-The received ancillary data is a null-terminated string containing +Receive the security context (the security label) +of the peer socket, +as provided by the active Linux Security Module (LSM), +such as SELinux or Smack. +The received ancillary data is a string containing the security context. -The receiver should allocate at least +Whether the string includes a terminating null byte +depends on the LSM;This seems to contradict the commit message. The commit message says that the string is terminated, but that the reported length might or might not be off-by-one (i.e., not count or count the '\0').
Quoted 2 lines
This text, however, is saying that in some cases there might not be a '\0' at all.
The TL;DR is that the byte after the returned buffer's declared length can't be trusted to be 0 - it is undefined and can be clobbered.
I have not read the full kernel implementation now, but it can already be seen in userspace that that adjacent byte can belong to a different data structue:
## How control messages are represented
The security context is returned to user space as a cmsghdr structure, as described in cmsg(3), where it is returned as a buffer of length cmsg_len:
struct cmsghdr {
size_t cmsg_len; /* data byte count including header */
/* some other fields */
/* followed by
unsigned char cmsg_data[]; */
};Reading beyond the declared cmsg_len is undefined, and callers don't get any guarantees about the byte following the csmg_data[] buffer.
## Iterating from userspace through multiple control messages
Iterating through the cmsgs is done with the API described in cmsg(3), CMSG_NXTHDR(). This is implemented as an inlined function in /usr/include/bits/socket.h. The function does a bunch of validation logic and then ends in this rather simple advancement logic:
__cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg
+ CMSG_ALIGN (__cmsg->cmsg_len));
return __cmsg;
So, the cmsgs with their cmsg_data[] buffers are next to each other in memory. They are aligned, but that still means that the byte after cmsg_data[] might be part of the next cmsg header or beyond the list of control messages.
---
The more I think about this, the more unsure I am that this is even worth documenting. In the end, anyone reading and interpreting this data probably needs to read the corresponding LSM anyway, and trailing null bytes are probably the least of their worries...?
Maybe it would be better to just say something like "The format of the security context is determined by the LSM responsible for it". WDYT?
–Günther
Alejandro Colomar
maintainerRe: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hi Günther,
Quoted 99 lines
Date: 2026-10-23 19:57:16+0200
From: Günther Noack <[email protected]>Hello Alejandro!
Quoted 15 lines · Alejandro Colomar
Quoted 15 lines
Date: 2026-10-21 23:22:53+0200
From: Günther Noack <[email protected]>Reword the description of
SCM_SECURITYto not be specific to SELinux.The security context is populated in
scm_passec()in linux.gitnet/core/scm.c, through thesecurity_secid_to_secctx()LSM hook, which is currently implemented by SELinux, Smack and AppArmor.Also clarify the properties of the returned string:
* There is no
NAME_MAXlimit on the length; SELinux contexts can be longer than that. If the control buffer is too small,put_cmsg()truncates the data and setsMSG_CTRUNC.Quoted 5 lines
Quoted 3 lines
* Whether the string is null-terminated also depends on the LSM:
SELinux includes the null byte in the length, butsmack_to_secctx()insecurity/smack/smack_lsm.cusesstrlen()and doesn't....
Ah, I can see that this is confusing; let me reformulate that without mentioning this
strlen()implementation detail. Smack returns a buffer with a given size *without* including the null byte, roughly like this (simplified):int len = strlen(skp->smk_known); /* populate */ cp->context = skp->smk_known; cp->len = len; <-- does not span the null byteReformulating to:
...but
smack_to_secctx()insecurity/smack/smack_lsm.csends a security context that does not end in a null byte.Quoted 57 lines
Quoted 13 lines
Fixes ffad6a017f91 (2018-07-28; "unix.7: Document SCM_SECURITY ancillary data")Cc Michael Kerrisk <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
This feature is also available in other LSMs. Unfortunately, they implemented it inconsistently and that complicates the description of how string boundaries are handled. Linux does indeed neither guarantee that this terminates with a NUL byte, nor thatNAME_MAXis large enough to hold it....
Quoted 26 lines
This is the verbose variant, but I am open for suggestions regarding what level of detail is appropriate here.
man/man7/unix.7 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)man/man7/unix.7 +1
-3@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the SELinux security label of the peer socket +Enables receiving of the security label of the peer socket in an ancillary message of type .B SCM_SECURITY (see below).@@ -544,13 +544,26 @@ message, the option must be enabled on the socket. .TP .B SCM_SECURITY -Receive the SELinux security context (the security label) -of the peer socket.man/man7/unix.7 message, the · line 554
Quoted 10 lines
man/man7/unix.7 +7
-2-The received ancillary data is a null-terminated string containing +Receive the security context (the security label) +of the peer socket, +as provided by the active Linux Security Module (LSM), +such as SELinux or Smack. +The received ancillary data is a string containing the security context. -The receiver should allocate at least +Whether the string includes a terminating null byte +depends on the LSM;This seems to contradict the commit message. The commit message says that the string is terminated, but that the reported length might or might not be off-by-one (i.e., not count or count the '\0').
Quoted 5 lines
Quoted 2 lines
This text, however, is saying that in some cases there might not be a '\0' at all.
The TL;DR is that the byte after the returned buffer's declared length can't be trusted to be 0 - it is undefined and can be clobbered.
Huh! This is to me a bug. Would you mind reporting them this as a bug and CCing me? I'd rather get this fixed in the kernel than documented as broken.
Especially, if they use strlen(3) internally, this sounds very much like a kernel bug, but even if not, it is clearly a kernel bug.
In any case, if we were to document this bug, we should not use the term string, because anything not containing a '\0' is not a string, by definition.
Quoted 39 lines
I have not read the full kernel implementation now, but it can already be seen in userspace that that adjacent byte can belong to a different data structue:
## How control messages are represented
The security context is returned to user space as a cmsghdr structure, as described in cmsg(3), where it is returned as a buffer of length
cmsg_len:struct cmsghdr { size_t cmsg_len; /* data byte count including header */ /* some other fields */ /* followed by unsigned char cmsg_data[]; */ };Reading beyond the declared
cmsg_lenis undefined, and callers don't get any guarantees about the byte following the csmg_data[] buffer.## Iterating from userspace through multiple control messages
Iterating through the cmsgs is done with the API described in cmsg(3),
CMSG_NXTHDR(). This is implemented as an inlined function in/usr/include/bits/socket.h. The function does a bunch of validation logic and then ends in this rather simple advancement logic:
__cmsg= (struct cmsghdr *) ((unsigned char *)__cmsg
+CMSG_ALIGN(__cmsg->cmsg_len));
return__cmsg;So, the cmsgs with their cmsg_data[] buffers are next to each other in memory. They are aligned, but that still means that the byte after cmsg_data[] might be part of the next cmsg header or beyond the list of control messages.
Quoted 7 lines
---
The more I think about this, the more unsure I am that this is even worth documenting. In the end, anyone reading and interpreting this data probably needs to read the corresponding LSM anyway, and trailing null bytes are probably the least of their worries...?
Not only that it's worth documenting, but this might be a vulnerability.
Quoted 3 lines
Maybe it would be better to just say something like "The format of the security context is determined by the LSM responsible for it". WDYT?
I'm unwilling to accept a nonstring as a valid format, unless very good reasons are stated. And if those reasons are stated as "that ship sailed long ago", the way to document this might very well be BUGS.
Have a lovely night!
Alex
Quoted 2 lines
–Günther
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hello Alejandro, Casey!
Quoted 106 lines · Alejandro Colomar
Quoted 96 lines
Date: 2026-10-23 19:57:16+0200
From: Günther Noack <[email protected]>Quoted 15 lines · Alejandro Colomar
Quoted 15 lines
Date: 2026-10-21 23:22:53+0200
From: Günther Noack <[email protected]>Reword the description of
SCM_SECURITYto not be specific to SELinux.The security context is populated in
scm_passec()in linux.gitnet/core/scm.c, through thesecurity_secid_to_secctx()LSM hook, which is currently implemented by SELinux, Smack and AppArmor.Also clarify the properties of the returned string:
* There is no
NAME_MAXlimit on the length; SELinux contexts can be longer than that. If the control buffer is too small,put_cmsg()truncates the data and setsMSG_CTRUNC.Quoted 5 lines
Quoted 3 lines
* Whether the string is null-terminated also depends on the LSM:
SELinux includes the null byte in the length, butsmack_to_secctx()insecurity/smack/smack_lsm.cusesstrlen()and doesn't....
Ah, I can see that this is confusing; let me reformulate that without mentioning this
strlen()implementation detail. Smack returns a buffer with a given size *without* including the null byte, roughly like this (simplified):int len = strlen(skp->smk_known); /* populate */ cp->context = skp->smk_known; cp->len = len; <-- does not span the null byteReformulating to:
...but
smack_to_secctx()insecurity/smack/smack_lsm.csends a security context that does not end in a null byte.Quoted 57 lines
Quoted 13 lines
Fixes ffad6a017f91 (2018-07-28; "unix.7: Document SCM_SECURITY ancillary data")Cc Michael Kerrisk <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
This feature is also available in other LSMs. Unfortunately, they implemented it inconsistently and that complicates the description of how string boundaries are handled. Linux does indeed neither guarantee that this terminates with a NUL byte, nor thatNAME_MAXis large enough to hold it....
Quoted 26 lines
This is the verbose variant, but I am open for suggestions regarding what level of detail is appropriate here.
man/man7/unix.7 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)man/man7/unix.7 +1
-3@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the SELinux security label of the peer socket +Enables receiving of the security label of the peer socket in an ancillary message of type .B SCM_SECURITY (see below).@@ -544,13 +544,26 @@ message, the option must be enabled on the socket. .TP .B SCM_SECURITY -Receive the SELinux security context (the security label) -of the peer socket.man/man7/unix.7 message, the · line 554
Quoted 10 lines
man/man7/unix.7 +7
-2-The received ancillary data is a null-terminated string containing +Receive the security context (the security label) +of the peer socket, +as provided by the active Linux Security Module (LSM), +such as SELinux or Smack. +The received ancillary data is a string containing the security context. -The receiver should allocate at least +Whether the string includes a terminating null byte +depends on the LSM;This seems to contradict the commit message. The commit message says that the string is terminated, but that the reported length might or might not be off-by-one (i.e., not count or count the '\0').
Quoted 5 lines
Quoted 2 lines
This text, however, is saying that in some cases there might not be a '\0' at all.
The TL;DR is that the byte after the returned buffer's declared length can't be trusted to be 0 - it is undefined and can be clobbered.
Huh! This is to me a bug. Would you mind reporting them this as a bug and CCing me? I'd rather get this fixed in the kernel than documented as broken.
Quoted 6 lines
Especially, if they use strlen(3) internally, this sounds very much like a kernel bug, but even if not, it is clearly a kernel bug.
In any case, if we were to document this bug, we should not use the term string, because anything not containing a '\0' is not a string, by definition.
Casey, would you be able to confirm whether this constitutes a Smack bug or is intentional?
The TL;DR is that we came across the function smack_to_secctx() in smack_lsm.c, which passes a Smack label string in a buffer without a terminating null byte. This is inconsistent with what SELinux and AppArmor do.
Before we start explaining so many corner cases in the man pages, I wanted to check -- is this something that Smack should fix, by including the zero byte?
I tried to double check the Smack userspace utilities but couldn't find any use of SCM_SECURITY there. (Is the feature unused?)
Quoted 47 lines
Quoted 39 lines
I have not read the full kernel implementation now, but it can already be seen in userspace that that adjacent byte can belong to a different data structue:
## How control messages are represented
The security context is returned to user space as a cmsghdr structure, as described in cmsg(3), where it is returned as a buffer of length
cmsg_len:struct cmsghdr { size_t cmsg_len; /* data byte count including header */ /* some other fields */ /* followed by unsigned char cmsg_data[]; */ };Reading beyond the declared
cmsg_lenis undefined, and callers don't get any guarantees about the byte following the csmg_data[] buffer.## Iterating from userspace through multiple control messages
Iterating through the cmsgs is done with the API described in cmsg(3),
CMSG_NXTHDR(). This is implemented as an inlined function in/usr/include/bits/socket.h. The function does a bunch of validation logic and then ends in this rather simple advancement logic:
__cmsg= (struct cmsghdr *) ((unsigned char *)__cmsg
+CMSG_ALIGN(__cmsg->cmsg_len));
return__cmsg;So, the cmsgs with their cmsg_data[] buffers are next to each other in memory. They are aligned, but that still means that the byte after cmsg_data[] might be part of the next cmsg header or beyond the list of control messages.
Quoted 7 lines
---
The more I think about this, the more unsure I am that this is even worth documenting. In the end, anyone reading and interpreting this data probably needs to read the corresponding LSM anyway, and trailing null bytes are probably the least of their worries...?
Quoted 8 lines
Not only that it's worth documenting, but this might be a vulnerability.
Quoted 2 lines
Maybe it would be better to just say something like "The format of the security context is determined by the LSM responsible for it". WDYT?
I'm unwilling to accept a nonstring as a valid format, unless very good reasons are stated. And if those reasons are stated as "that ship sailed long ago", the way to document this might very well be BUGS.
Point taken and agreed that it would be better to call it a "buffer" rather than a "string" when it does not have the null terminator.
It does seem that this is used also outside of UNIX Domain Sockets:IP_PASSSEC(2const) says:
The security context returned in the SCM_SECURITY ancillary message is of the same format as the one described in SO_PEERSEC(2const).
And looking this format up in SO_PEERSEC(2const), we find:
The security context string may include a terminating null character in the returned length, but is not guaranteed to do so: a security context "foo" might be represented as either {'f','o','o'} of length 3 or {'f','o','o','\0'} of length 4, which are considered to be interchangeable. The string is printable, does not contain non- terminating null characters, and is in an unspecified encoding (in particular, it is not guaranteed to be ASCII or UTF-8).
So it seems that these "buffer" (not "string") semantics exist there as well. Maybe it is intentional then that it is treated as a buffer rather than a string?
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
–Günther
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITY
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Does that sound reasonable? Let me know what you think.
I removed the wording "There is no fixed limit ...", because it should be a given that callers allocate enough buffer space for receiving and check the truncation flag. (The more important part is that we remove the previous wording which suggested that it would fit into NAME_MAX.)
Given that SCM_SECURITY on "real" networks seems to have the same "buffer, not string" semantics, it feels fair to express it that way? People who want to read the security context will anyway need to read up on the exact format used by the LSM in order to attribute any meaning to it.
–Günther
P.S.: I had a hard time finding many usage examples. The main user of SCM_SECURITY seems to be systemd's journald, which uses it to log the SELinux security label. That code can deal with both null terminated strings and ones where it is missing (due to truncation), and there is a comment indicating that they are aware of possible truncation.
Alejandro Colomar
maintainerRe: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hi Günther,
Quoted 14 lines
Date: 2026-10-27 09:54:51+0100
From: Günther Noack <[email protected]>Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITY
Quoted 7 lines
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Let's pause the discussion of the specific text for now.
I have questions about the exact format used by each LSM. For example, you say that SELinux guarantees a string. Does it count the '\0' as part of the data size? Or is it guaranteed to exist but not counted?
Same question for the other LSMs.
Have a lovely night!
Alex
Quoted 20 lines
Does that sound reasonable? Let me know what you think.
I removed the wording "There is no fixed limit ...", because it should be a given that callers allocate enough buffer space for receiving and check the truncation flag. (The more important part is that we remove the previous wording which suggested that it would fit into
NAME_MAX.)Given that
SCM_SECURITYon "real" networks seems to have the same "buffer, not string" semantics, it feels fair to express it that way? People who want to read the security context will anyway need to read up on the exact format used by the LSM in order to attribute any meaning to it.–Günther
P.S.: I had a hard time finding many usage examples. The main user ofSCM_SECURITYseems to be systemd's journald, which uses it to log the SELinux security label. That code can deal with both null terminated strings and ones where it is missing (due to truncation), and there is a comment indicating that they are aware of possible truncation.
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hello Alejandro!
Quoted 22 lines · Alejandro Colomar
Quoted 14 lines
Date: 2026-10-27 09:54:51+0100
From: Günther Noack <[email protected]>Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITYQuoted 7 lines
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Quoted 7 lines
Let's pause the discussion of the specific text for now.
I have questions about the exact format used by each LSM. For example, you say that SELinux guarantees a string. Does it count the '\0' as part of the data size? Or is it guaranteed to exist but not counted?
Same question for the other LSMs.
Yes, SELinux counts the '\0' as part of the buffer size for the SCM_SECURITY security context.
Examples:
* If the label is "foo", it'll return {'f', 'o', 'o', '\0'} with payload size 4.
* If the reader calls recvmsg() but preallocates too little space in the msg_control buffer, this can get truncated though, and then it won't end with '\0':
{'e', 'x', 'a', 'm', 'p'} with payload size 5 (truncated)
Other LSMs:
* Smack excludes the null byte for SCM_SECURITY (smack_to_secctx()) (but irritatingly it does count the null byte when a label is returned through SO_PEERSEC (smack_socket_getpeersec_stream()). Both functions are in security/smack/smack_lsm.c.
* AppArmor excludes the null byte for SCM_SECURITY as well. Implementation is in apparmor_label_to_secctx(), where it populates the struct lsm_context *cp using:
len = aa_label_asxprint(&cp->context...)
and then sets
cp->len = len;
The function aa_label_asxprint() returns the length without trailing null byte, as can be seen in its implementation.
SELinux, Smack and AppArmor are the only LSMs that implement the secid_to_secctx() hook, which is the hook that defines the payload contents. (For reference, the higher level common SCM logic like the truncation is in net/core/scm.c.)
All reasoning is based on reading the code (with some AI assistance to point me to the right places). I have not tried it out in a running system, but it seems to check out.
–Günther
Alejandro Colomar
maintainerRe: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hi Günther,
Quoted 30 lines
Date: 2026-10-27 23:30:59+0100
From: Günther Noack <[email protected]>Hello Alejandro!
Quoted 24 lines · Alejandro Colomar
Quoted 14 lines
Date: 2026-10-27 09:54:51+0100
From: Günther Noack <[email protected]>Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITYQuoted 7 lines
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Let's pause the discussion of the specific text for now.
Quoted 8 lines
Quoted 5 lines
I have questions about the exact format used by each LSM. For example, you say that SELinux guarantees a string. Does it count the '\0' as part of the data size? Or is it guaranteed to exist but not counted?
Same question for the other LSMs.
Yes, SELinux counts the '\0' as part of the buffer size for the
SCM_SECURITYsecurity context.
Ok.
Quoted 7 lines
Examples:
* If the label is "foo", it'll return {'f', 'o', 'o', '\0'} with payload size 4.
* If the reader callsrecvmsg()but preallocates too little space in themsg_controlbuffer, this can get truncated though, and then it won't end with '\0':
{'e', 'x', 'a', 'm', 'p'} with payload size 5 (truncated)
Ouch! So, no string guarantees here either, actually.
Quoted 6 lines
Other LSMs:
* Smack excludes the null byte for
SCM_SECURITY(smack_to_secctx()) (but irritatingly it does count the null byte when a label is returned throughSO_PEERSEC(smack_socket_getpeersec_stream()). Both functions are insecurity/smack/smack_lsm.c.
And as we've seen, no string guarantees, IIUC.
Quoted 5 lines
* AppArmor excludes the null byte for
SCM_SECURITYas well. Implementation is inapparmor_label_to_secctx(), where it populates the structlsm_context*cp using:
Quoted 8 lines
len = aa_label_asxprint(&cp->context...)and then sets
cp->len = len;The function
aa_label_asxprint()returns the length without trailing null byte, as can be seen in its implementation.
How does it behave if there's not enough space? Does AppArmor guarantee a string?
Cheers,
Alex
Quoted 10 lines
SELinux, Smack and AppArmor are the only LSMs that implement the
secid_to_secctx()hook, which is the hook that defines the payload contents. (For reference, the higher level common SCM logic like the truncation is innet/core/scm.c.)All reasoning is based on reading the code (with some AI assistance to point me to the right places). I have not tried it out in a running system, but it seems to check out.
–Günther
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hello Alejandro!
Quoted 39 lines · Alejandro Colomar
Quoted 27 lines
Date: 2026-10-27 23:30:59+0100
From: Günther Noack <[email protected]>Quoted 24 lines · Alejandro Colomar
Quoted 14 lines
Date: 2026-10-27 09:54:51+0100
From: Günther Noack <[email protected]>Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITYQuoted 7 lines
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Let's pause the discussion of the specific text for now.
Quoted 8 lines
Quoted 5 lines
I have questions about the exact format used by each LSM. For example, you say that SELinux guarantees a string. Does it count the '\0' as part of the data size? Or is it guaranteed to exist but not counted?
Same question for the other LSMs.
Yes, SELinux counts the '\0' as part of the buffer size for the
SCM_SECURITYsecurity context.Ok.
Quoted 1 line
Quoted 8 lines
Quoted 6 lines
Examples:
* If the label is "foo", it'll return {'f', 'o', 'o', '\0'} with payload size 4.
* If the reader callsrecvmsg()but preallocates too little space in themsg_controlbuffer, this can get truncated though, and then it won't end with '\0':
{'e', 'x', 'a', 'm', 'p'} with payload size 5 (truncated)Ouch! So, no string guarantees here either, actually.
Correct. Callers have to deal with the possibility of truncation, which strips away the null byte.
Quoted 8 lines
Quoted 6 lines
Other LSMs:
* Smack excludes the null byte for
SCM_SECURITY(smack_to_secctx()) (but irritatingly it does count the null byte when a label is returned throughSO_PEERSEC(smack_socket_getpeersec_stream()). Both functions are insecurity/smack/smack_lsm.c.And as we've seen, no string guarantees, IIUC.
Correct.
Quoted 9 lines
Quoted 9 lines
* AppArmor excludes the null byte for
SCM_SECURITYas well. Implementation is inapparmor_label_to_secctx(), where it populates the structlsm_context*cp using:len = aa_label_asxprint(&cp->context...)and then sets
Quoted 7 lines
Quoted 4 lines
cp->len = len;The function
aa_label_asxprint()returns the length without trailing null byte, as can be seen in its implementation.How does it behave if there's not enough space? Does AppArmor guarantee a string?
The truncation case always strips off the null byte at the end of the buffer. This is handled **independent of the LSM** in the common net/core/scm.c layer one level above - it *always* kicks in when truncation happens.
To sum it all up in a table: The only case where the null byte is included in the buffer is in SELinux, when the generic SCM layer does not need to do truncation:
normal case truncation case
--------------------------------------------------------------
SELinux has trailing null byte no trailing null byte AppArmor no trailing null byte no trailing null byte Smack no trailing null byte no trailing null byte
(other LSMs don't have the feature at all)
–Günther
Alejandro Colomar
maintainerRe: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hi Günther,
Quoted 52 lines
Date: 2026-10-28 07:19:28+0100
From: Günther Noack <[email protected]>Hello Alejandro!
Quoted 46 lines · Alejandro Colomar
Quoted 27 lines
Date: 2026-10-27 23:30:59+0100
From: Günther Noack <[email protected]>Quoted 24 lines · Alejandro Colomar
Quoted 14 lines
Date: 2026-10-27 09:54:51+0100
From: Günther Noack <[email protected]>Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITYQuoted 7 lines
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Let's pause the discussion of the specific text for now.
Quoted 8 lines
Quoted 5 lines
I have questions about the exact format used by each LSM. For example, you say that SELinux guarantees a string. Does it count the '\0' as part of the data size? Or is it guaranteed to exist but not counted?
Same question for the other LSMs.
Yes, SELinux counts the '\0' as part of the buffer size for the
SCM_SECURITYsecurity context.Ok.
Quoted 7 lines
Examples:
* If the label is "foo", it'll return {'f', 'o', 'o', '\0'} with payload size 4.
* If the reader callsrecvmsg()but preallocates too little space in themsg_controlbuffer, this can get truncated though, and then it won't end with '\0':
{'e', 'x', 'a', 'm', 'p'} with payload size 5 (truncated)
Quoted 4 lines
Quoted 1 line
Ouch! So, no string guarantees here either, actually.
Correct. Callers have to deal with the possibility of truncation, which strips away the null byte.
Is this true for every LSM? Do any LSMs guarantee a string even under truncation?
Quoted 25 lines
Quoted 8 lines
Quoted 6 lines
Other LSMs:
* Smack excludes the null byte for
SCM_SECURITY(smack_to_secctx()) (but irritatingly it does count the null byte when a label is returned throughSO_PEERSEC(smack_socket_getpeersec_stream()). Both functions are insecurity/smack/smack_lsm.c.And as we've seen, no string guarantees, IIUC.
Correct.
Quoted 14 lines
Quoted 13 lines
* AppArmor excludes the null byte for
SCM_SECURITYas well. Implementation is inapparmor_label_to_secctx(), where it populates the structlsm_context*cp using:len = aa_label_asxprint(&cp->context...)and then sets
cp->len = len;The function
aa_label_asxprint()returns the length without trailing null byte, as can be seen in its implementation.
Quoted 7 lines
Quoted 2 lines
How does it behave if there's not enough space? Does AppArmor guarantee a string?
The truncation case always strips off the null byte at the end of the buffer. This is handled **independent of the LSM** in the common
net/core/scm.clayer one level above - it *always* kicks in when truncation happens.
Hmmmm. I believe that layer should guarantee a null byte when it truncates the data. It should be like strscpy(), which guarantees a correct string even on truncation.
This seems to be another bug.
Quoted 11 lines
To sum it all up in a table: The only case where the null byte is included in the buffer is in SELinux, when the generic SCM layer does not need to do truncation:
normal case truncation case
--------------------------------------------------------------SELinux has trailing null byte no trailing null byte AppArmor no trailing null byte no trailing null byte Smack no trailing null byte no trailing null byte(other LSMs don't have the feature at all)
Thanks for the table! This seems to me to be 3 bugs: one in AppArmor, the same one in Smack, and one in the upper layer which corrupts the string when truncating. I wonder if we can do better in the truncation case, or if it's too late for that.
Would you mind CCing the maintainers of the upper layer in net/core/scm.c?
Have a lovely day!
Alex
Quoted 2 lines
–Günther
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hello!
Quoted 47 lines · Alejandro Colomar
Quoted 47 lines · Alejandro Colomar
Quoted 46 lines
Quoted 27 lines
Date: 2026-10-27 23:30:59+0100
From: Günther Noack <[email protected]>Quoted 24 lines · Alejandro Colomar
Quoted 14 lines
Date: 2026-10-27 09:54:51+0100
From: Günther Noack <[email protected]>Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITYQuoted 7 lines
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Let's pause the discussion of the specific text for now.
Quoted 8 lines
Quoted 5 lines
I have questions about the exact format used by each LSM. For example, you say that SELinux guarantees a string. Does it count the '\0' as part of the data size? Or is it guaranteed to exist but not counted?
Same question for the other LSMs.
Yes, SELinux counts the '\0' as part of the buffer size for the
SCM_SECURITYsecurity context.Ok.
Quoted 7 lines
Examples:
* If the label is "foo", it'll return {'f', 'o', 'o', '\0'} with payload size 4.
* If the reader callsrecvmsg()but preallocates too little space in themsg_controlbuffer, this can get truncated though, and then it won't end with '\0':
{'e', 'x', 'a', 'm', 'p'} with payload size 5 (truncated)
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Ouch! So, no string guarantees here either, actually.
Correct. Callers have to deal with the possibility of truncation, which strips away the null byte.
Is this true for every LSM? Do any LSMs guarantee a string even under truncation?
Yes, it is true for every LSM (as discussed below) and none of the LSMs can guarantee a string under truncation.
Quoted 21 lines
Quoted 13 lines
Quoted 13 lines
Quoted 12 lines
* AppArmor excludes the null byte for
SCM_SECURITYas well. Implementation is inapparmor_label_to_secctx(), where it populates the structlsm_context*cp using:len = aa_label_asxprint(&cp->context...)and then sets
cp->len = len;The function
aa_label_asxprint()returns the length without trailing null byte, as can be seen in its implementation.Quoted 7 lines
Quoted 2 lines
How does it behave if there's not enough space? Does AppArmor guarantee a string?
The truncation case always strips off the null byte at the end of the buffer. This is handled **independent of the LSM** in the common
net/core/scm.clayer one level above - it *always* kicks in when truncation happens.
Quoted 5 lines
Hmmmm. I believe that layer should guarantee a null byte when it truncates the data. It should be like
strscpy(), which guarantees a correct string even on truncation.This seems to be another bug.
(Bringing it up below together with the AA/Smack payloads which are also not null-terminated.)
Quoted 12 lines
Quoted 11 lines
To sum it all up in a table: The only case where the null byte is included in the buffer is in SELinux, when the generic SCM layer does not need to do truncation:
normal case truncation case
--------------------------------------------------------------SELinux has trailing null byte no trailing null byte AppArmor no trailing null byte no trailing null byte Smack no trailing null byte no trailing null byte(other LSMs don't have the feature at all)
Quoted 7 lines
Thanks for the table! This seems to me to be 3 bugs: one in AppArmor, the same one in Smack, and one in the upper layer which corrupts the string when truncating. I wonder if we can do better in the truncation case, or if it's too late for that.
Would you mind CCing the maintainers of the upper layer in
net/core/scm.c?
Adding Eric Dumazet, Paolo Abeni and Willem de Brujin. (Kuniyuki Iwashima is already in CC.)
Hello maintainers of NETWORKING [SOCKETS]! :)
We are unsure in this documentation review what
the intended format of payloads is which are returned by SCM_SECURITY:
They have previously been documented as zero-terminated strings (for the SELinux case), but in the case of truncation and in the case of the two other supported LSMs, there implementation does not return a trailing zero byte.
Could you please confirm what the intended interface for SCM_SECURITY is? The two variants we have been discussing are:
Variant A:
The returned payload is a byte buffer whose contents are defined by the respective LSM (and which are not necessarily zero-terminated).
Concrete wording proposal for this variant is in:
https://lore.kernel.org/all/[email protected]/
Variant B:
The returned payload is a string which should be zero-terminated.
(But in this case, the Smack and Apparmor implementation, as well as the generic truncation are arguably not doing that right.)
The documentation commit at the top of this dicussion is documenting the current implementation, but it becomes lengthy and it feels like it could be crisper if we could document the original intent:
https://lore.kernel.org/all/[email protected]/
I would appreciate your feedback to un-wedge the review. :)
Thanks!
–Günther
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Quoted 124 lines · Günther Noack
Hello!
Quoted 47 lines · Alejandro Colomar
Quoted 47 lines · Alejandro Colomar
Quoted 46 lines
Quoted 27 lines
Date: 2026-10-27 23:30:59+0100
From: Günther Noack <[email protected]>Quoted 24 lines · Alejandro Colomar
Quoted 14 lines
Date: 2026-10-27 09:54:51+0100
From: Günther Noack <[email protected]>Quoted 4 lines · Günther Noack
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
To make a more concrete and constructive wording proposal:
SCM_SECURITYQuoted 7 lines
Receive the security context (the security label) of the peer socket, as provided by the active Linux Security Module (LSM). The received ancillary data is a byte buffer.
The exact format of the security context buffer is defined by the active major LSM. For example, SELinux returns a SELinux label as a string (including a terminating null byte).
Let's pause the discussion of the specific text for now.
Quoted 8 lines
Quoted 5 lines
I have questions about the exact format used by each LSM. For example, you say that SELinux guarantees a string. Does it count the '\0' as part of the data size? Or is it guaranteed to exist but not counted?
Same question for the other LSMs.
Yes, SELinux counts the '\0' as part of the buffer size for the
SCM_SECURITYsecurity context.Ok.
Quoted 7 lines
Examples:
* If the label is "foo", it'll return {'f', 'o', 'o', '\0'} with payload size 4.
* If the reader callsrecvmsg()but preallocates too little space in themsg_controlbuffer, this can get truncated though, and then it won't end with '\0':
{'e', 'x', 'a', 'm', 'p'} with payload size 5 (truncated)Quoted 7 lines
Quoted 4 lines
Quoted 1 line
Ouch! So, no string guarantees here either, actually.
Correct. Callers have to deal with the possibility of truncation, which strips away the null byte.
Is this true for every LSM? Do any LSMs guarantee a string even under truncation?
Yes, it is true for every LSM (as discussed below) and none of the LSMs can guarantee a string under truncation.
Quoted 21 lines
Quoted 13 lines
Quoted 13 lines
Quoted 12 lines
* AppArmor excludes the null byte for
SCM_SECURITYas well. Implementation is inapparmor_label_to_secctx(), where it populates the structlsm_context*cp using:len = aa_label_asxprint(&cp->context...)and then sets
cp->len = len;The function
aa_label_asxprint()returns the length without trailing null byte, as can be seen in its implementation.Quoted 7 lines
Quoted 2 lines
How does it behave if there's not enough space? Does AppArmor guarantee a string?
The truncation case always strips off the null byte at the end of the buffer. This is handled **independent of the LSM** in the common
net/core/scm.clayer one level above - it *always* kicks in when truncation happens.Quoted 5 lines
Hmmmm. I believe that layer should guarantee a null byte when it truncates the data. It should be like
strscpy(), which guarantees a correct string even on truncation.This seems to be another bug.
(Bringing it up below together with the AA/Smack payloads which are also not null-terminated.)
Quoted 12 lines
Quoted 11 lines
To sum it all up in a table: The only case where the null byte is included in the buffer is in SELinux, when the generic SCM layer does not need to do truncation:
normal case truncation case
--------------------------------------------------------------SELinux has trailing null byte no trailing null byte AppArmor no trailing null byte no trailing null byte Smack no trailing null byte no trailing null byte(other LSMs don't have the feature at all)
Quoted 7 lines
Thanks for the table! This seems to me to be 3 bugs: one in AppArmor, the same one in Smack, and one in the upper layer which corrupts the string when truncating. I wonder if we can do better in the truncation case, or if it's too late for that.
Would you mind CCing the maintainers of the upper layer in
net/core/scm.c?Adding Eric Dumazet, Paolo Abeni and Willem de Brujin. (Kuniyuki Iwashima is already in CC.)
Hello maintainers of NETWORKING [SOCKETS]! :)
We are unsure in this documentation review what
the intended format of payloads is which are returned bySCM_SECURITY:
They have previously been documented as zero-terminated strings (for the SELinux case), but in the case of truncation and in the case of the two other supported LSMs, there implementation does not return a trailing zero byte.
Quoted 6 lines
Could you please confirm what the intended interface for
SCM_SECURITYis? The two variants we have been discussing are:Variant A:
The returned payload is a byte buffer whose contents are defined by the respective LSM (and which are not necessarily zero-terminated).
+1, basically each scm data is binary.
I think it's just man page was not updated for other LSMs.
Quoted 20 lines
Concrete wording proposal for this variant is in:
https://lore.kernel.org/all/[email protected]/Variant B:
The returned payload is a string which should be zero-terminated.(But in this case, the Smack and Apparmor implementation, as well as the generic truncation are arguably not doing that right.)
The documentation commit at the top of this dicussion is documenting the current implementation, but it becomes lengthy and it feels like it could be crisper if we could document the original intent:
https://lore.kernel.org/all/[email protected]/I would appreciate your feedback to un-wedge the review. :)
Thanks!
–Günther
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hello!
Quoted 37 lines · Kuniyuki Iwashima
Quoted 36 lines · Günther Noack
Quoted 12 lines · Alejandro Colomar
Quoted 11 lines
To sum it all up in a table: The only case where the null byte is included in the buffer is in SELinux, when the generic SCM layer does not need to do truncation:
normal case truncation case
--------------------------------------------------------------SELinux has trailing null byte no trailing null byte AppArmor no trailing null byte no trailing null byte Smack no trailing null byte no trailing null byte(other LSMs don't have the feature at all)
Quoted 7 lines
Thanks for the table! This seems to me to be 3 bugs: one in AppArmor, the same one in Smack, and one in the upper layer which corrupts the string when truncating. I wonder if we can do better in the truncation case, or if it's too late for that.
Would you mind CCing the maintainers of the upper layer in
net/core/scm.c?Adding Eric Dumazet, Paolo Abeni and Willem de Brujin. (Kuniyuki Iwashima is already in CC.)
Hello maintainers of NETWORKING [SOCKETS]! :)
We are unsure in this documentation review what
the intended format of payloads is which are returned bySCM_SECURITY:
They have previously been documented as zero-terminated strings (for the SELinux case), but in the case of truncation and in the case of the two other supported LSMs, there implementation does not return a trailing zero byte.Could you please confirm what the intended interface for
SCM_SECURITYis? The two variants we have been discussing are:
Quoted 7 lines
Quoted 3 lines
Variant A:
The returned payload is a byte buffer whose contents are defined by the respective LSM (and which are not necessarily zero-terminated).+1, basically each scm data is binary.
I think it's just man page was not updated for other LSMs.
Thank you for the confirmation, Kuniyuki!
Quoted 2 lines
Quoted 2 lines
Concrete wording proposal for this variant is in:
https://lore.kernel.org/all/[email protected]/
^ This
Alejandro, in this case, and to make some progress on this patch set, I'll resend the patch set with the "binary buffer" variant that I proposed in the other mail. Let's discuss the wording there, if needed.
–Günther
Re: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
In reply to Günther NoackQuoted 103 lines · Günther Noack
Hello Alejandro, Casey!
Quoted 100 lines · Alejandro Colomar
Quoted 92 lines
Date: 2026-10-23 19:57:16+0200
From: Günther Noack <[email protected]>Quoted 11 lines · Alejandro Colomar
Quoted 11 lines
Date: 2026-10-21 23:22:53+0200
From: Günther Noack <[email protected]>Reword the description of
SCM_SECURITYto not be specific to SELinux.The security context is populated in
scm_passec()in linux.gitnet/core/scm.c, through thesecurity_secid_to_secctx()LSM hook, which is currently implemented by SELinux, Smack and AppArmor.Also clarify the properties of the returned string:
Quoted 8 lines
Quoted 7 lines
* There is no
NAME_MAXlimit on the length; SELinux contexts can be longer than that. If the control buffer is too small,put_cmsg()truncates the data and setsMSG_CTRUNC.* Whether the string is null-terminated also depends on the LSM:
SELinux includes the null byte in the length, butsmack_to_secctx()insecurity/smack/smack_lsm.cusesstrlen()and doesn't....
Ah, I can see that this is confusing; let me reformulate that without mentioning this
strlen()implementation detail. Smack returns a buffer with a given size *without* including the null byte, roughly like this (simplified):int len = strlen(skp->smk_known); /* populate */ cp->context = skp->smk_known; cp->len = len; <-- does not span the null byteReformulating to:
...but
smack_to_secctx()insecurity/smack/smack_lsm.csends a security context that does not end in a null byte.Quoted 55 lines
Quoted 13 lines
Fixes ffad6a017f91 (2018-07-28; "unix.7: Document SCM_SECURITY ancillary data")Cc Michael Kerrisk <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>---
Notes:
This feature is also available in other LSMs. Unfortunately, they implemented it inconsistently and that complicates the description of how string boundaries are handled. Linux does indeed neither guarantee that this terminates with a NUL byte, nor thatNAME_MAXis large enough to hold it....
Quoted 26 lines
This is the verbose variant, but I am open for suggestions regarding what level of detail is appropriate here.
man/man7/unix.7 | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-)man/man7/unix.7 +1
-3@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the SELinux security label of the peer socket +Enables receiving of the security label of the peer socket in an ancillary message of type .B SCM_SECURITY (see below).@@ -544,13 +544,26 @@ message, the option must be enabled on the socket. .TP .B SCM_SECURITY -Receive the SELinux security context (the security label) -of the peer socket.man/man7/unix.7 message, the · line 554
Quoted 10 lines
man/man7/unix.7 +7
-2-The received ancillary data is a null-terminated string containing +Receive the security context (the security label) +of the peer socket, +as provided by the active Linux Security Module (LSM), +such as SELinux or Smack. +The received ancillary data is a string containing the security context. -The receiver should allocate at least +Whether the string includes a terminating null byte +depends on the LSM;This seems to contradict the commit message. The commit message says that the string is terminated, but that the reported length might or might not be off-by-one (i.e., not count or count the '\0').
Quoted 4 lines
Quoted 2 lines
This text, however, is saying that in some cases there might not be a '\0' at all.
The TL;DR is that the byte after the returned buffer's declared length can't be trusted to be 0 - it is undefined and can be clobbered.
Huh! This is to me a bug. Would you mind reporting them this as a bug and CCing me? I'd rather get this fixed in the kernel than documented as broken.
Quoted 8 lines
Quoted 6 lines
Especially, if they use strlen(3) internally, this sounds very much like a kernel bug, but even if not, it is clearly a kernel bug.
In any case, if we were to document this bug, we should not use the term string, because anything not containing a '\0' is not a string, by definition.
Casey, would you be able to confirm whether this constitutes a Smack bug or is intentional?
Inclusion of a null byte for C string interfaces has been a topic of debate since about 1980. At the time this code was written my understanding was that the data SCM_SECURITY returned could not be assumed to be a C string. Hence, the size of the data, not the size of a string. The null byte isn't considered a part of the string, as reported by strlen().
So, the existing behavior is intentional, but I'm willing to have it considered a bug if (as of today) everyone thinks the data should include a null byte.
Quoted 11 lines
The TL;DR is that we came across the function
smack_to_secctx()insmack_lsm.c, which passes a Smack label string in a buffer without a terminating null byte. This is inconsistent with what SELinux and AppArmor do.Before we start explaining so many corner cases in the man pages, I wanted to check -- is this something that Smack should fix, by including the zero byte?
I tried to double check the Smack userspace utilities but couldn't find any use of
SCM_SECURITYthere. (Is the feature unused?)
The Smack userspace utilities (github.com://smackteam/smack.git) represent a limited Smack system implementation. SCM_SECURITY is used in at least a couple of important embedded and enterprise implementations.
Quoted 71 lines
Quoted 46 lines
Quoted 39 lines
I have not read the full kernel implementation now, but it can already be seen in userspace that that adjacent byte can belong to a different data structue:
## How control messages are represented
The security context is returned to user space as a cmsghdr structure, as described in cmsg(3), where it is returned as a buffer of length
cmsg_len:struct cmsghdr { size_t cmsg_len; /* data byte count including header */ /* some other fields */ /* followed by unsigned char cmsg_data[]; */ };Reading beyond the declared
cmsg_lenis undefined, and callers don't get any guarantees about the byte following the csmg_data[] buffer.## Iterating from userspace through multiple control messages
Iterating through the cmsgs is done with the API described in cmsg(3),
CMSG_NXTHDR(). This is implemented as an inlined function in/usr/include/bits/socket.h. The function does a bunch of validation logic and then ends in this rather simple advancement logic:
__cmsg= (struct cmsghdr *) ((unsigned char *)__cmsg
+CMSG_ALIGN(__cmsg->cmsg_len));
return__cmsg;So, the cmsgs with their cmsg_data[] buffers are next to each other in memory. They are aligned, but that still means that the byte after cmsg_data[] might be part of the next cmsg header or beyond the list of control messages.
Quoted 7 lines
---
The more I think about this, the more unsure I am that this is even worth documenting. In the end, anyone reading and interpreting this data probably needs to read the corresponding LSM anyway, and trailing null bytes are probably the least of their worries...?
Quoted 6 lines
Not only that it's worth documenting, but this might be a vulnerability.
Quoted 2 lines
Maybe it would be better to just say something like "The format of the security context is determined by the LSM responsible for it". WDYT?
I'm unwilling to accept a nonstring as a valid format, unless very good reasons are stated. And if those reasons are stated as "that ship sailed long ago", the way to document this might very well be BUGS.
Point taken and agreed that it would be better to call it a "buffer" rather than a "string" when it does not have the null terminator.
It does seem that this is used also outside of UNIX Domain Sockets:
IP_PASSSEC(2const)says:The security context returned in the
SCM_SECURITYancillary message is of the same format as the one described inSO_PEERSEC(2const).And looking this format up in
SO_PEERSEC(2const), we find:The security context string may include a terminating null character in the returned length, but is not guaranteed to do so: a security context "foo" might be represented as either {'f','o','o'} of length 3 or {'f','o','o','\0'} of length 4, which are considered to be interchangeable. The string is printable, does not contain non- terminating null characters, and is in an unspecified encoding (in particular, it is not guaranteed to be ASCII or UTF-8).
Quoted 3 lines
So it seems that these "buffer" (not "string") semantics exist there as well. Maybe it is intentional then that it is treated as a buffer rather than a string?
I'm easy. If there is a strong desire to make SCM_SECURITY a string Smack can be changed easily enough.
Quoted 8 lines
I'm still leaning towards documenting it as a buffer with implementation-defined contents which are provided by a LSM. How these buffer contents are interpreted is depending on the LSM in use anyway.
–Günther
Alejandro Colomar
maintainerRe: [PATCH 4/7] man/man7/unix.7: SCM_SECURITY: Generalize to other LSMs, not just SELinux
Hi Casey,
Quoted 3 lines
Date: 2026-10-27 09:32:57-0700
From: Casey Schaufler <[email protected]>
[...]
Quoted 23 lines
Quoted 8 lines
Quoted 8 lines
Quoted 4 lines
Quoted 2 lines
This text, however, is saying that in some cases there might not be a '\0' at all.
The TL;DR is that the byte after the returned buffer's declared length can't be trusted to be 0 - it is undefined and can be clobbered.
Huh! This is to me a bug. Would you mind reporting them this as a bug and CCing me? I'd rather get this fixed in the kernel than documented as broken.
Quoted 8 lines
Quoted 6 lines
Especially, if they use strlen(3) internally, this sounds very much like a kernel bug, but even if not, it is clearly a kernel bug.
In any case, if we were to document this bug, we should not use the term string, because anything not containing a '\0' is not a string, by definition.
Casey, would you be able to confirm whether this constitutes a Smack bug or is intentional?
Inclusion of a null byte for C string interfaces has been a topic of debate since about 1980. At the time this code was written my understanding was that the data
SCM_SECURITYreturned could not be assumed to be a C string. Hence, the size of the data, not the size of a string. The null byte isn't considered a part of the string, as reported bystrlen().
Quoted 3 lines
So, the existing behavior is intentional, but I'm willing to have it considered a bug if (as of today) everyone thinks the data should include a null byte.
Yup, I think the issue of strings has more or less settled towards using C strings everywhere, with other formats --such as fixed-width buffers from utmp(5)-- being phased out. Most of libc takes C strings, and so using C strings everywhere is safer, as it avoids having to manually handle the bytes.
Quoted 88 lines
Quoted 11 lines
The TL;DR is that we came across the function
smack_to_secctx()insmack_lsm.c, which passes a Smack label string in a buffer without a terminating null byte. This is inconsistent with what SELinux and AppArmor do.Before we start explaining so many corner cases in the man pages, I wanted to check -- is this something that Smack should fix, by including the zero byte?
I tried to double check the Smack userspace utilities but couldn't find any use of
SCM_SECURITYthere. (Is the feature unused?)The Smack userspace utilities (github.com://smackteam/smack.git) represent a limited Smack system implementation.
SCM_SECURITYis used in at least a couple of important embedded and enterprise implementations.Quoted 71 lines
Quoted 46 lines
Quoted 39 lines
I have not read the full kernel implementation now, but it can already be seen in userspace that that adjacent byte can belong to a different data structue:
## How control messages are represented
The security context is returned to user space as a cmsghdr structure, as described in cmsg(3), where it is returned as a buffer of length
cmsg_len:struct cmsghdr { size_t cmsg_len; /* data byte count including header */ /* some other fields */ /* followed by unsigned char cmsg_data[]; */ };Reading beyond the declared
cmsg_lenis undefined, and callers don't get any guarantees about the byte following the csmg_data[] buffer.## Iterating from userspace through multiple control messages
Iterating through the cmsgs is done with the API described in cmsg(3),
CMSG_NXTHDR(). This is implemented as an inlined function in/usr/include/bits/socket.h. The function does a bunch of validation logic and then ends in this rather simple advancement logic:
__cmsg= (struct cmsghdr *) ((unsigned char *)__cmsg
+CMSG_ALIGN(__cmsg->cmsg_len));
return__cmsg;So, the cmsgs with their cmsg_data[] buffers are next to each other in memory. They are aligned, but that still means that the byte after cmsg_data[] might be part of the next cmsg header or beyond the list of control messages.
Quoted 7 lines
---
The more I think about this, the more unsure I am that this is even worth documenting. In the end, anyone reading and interpreting this data probably needs to read the corresponding LSM anyway, and trailing null bytes are probably the least of their worries...?
Quoted 6 lines
Not only that it's worth documenting, but this might be a vulnerability.
Quoted 2 lines
Maybe it would be better to just say something like "The format of the security context is determined by the LSM responsible for it". WDYT?
I'm unwilling to accept a nonstring as a valid format, unless very good reasons are stated. And if those reasons are stated as "that ship sailed long ago", the way to document this might very well be BUGS.
Point taken and agreed that it would be better to call it a "buffer" rather than a "string" when it does not have the null terminator.
It does seem that this is used also outside of UNIX Domain Sockets:
IP_PASSSEC(2const)says:The security context returned in the
SCM_SECURITYancillary message is of the same format as the one described inSO_PEERSEC(2const).And looking this format up in
SO_PEERSEC(2const), we find:The security context string may include a terminating null character in the returned length, but is not guaranteed to do so: a security context "foo" might be represented as either {'f','o','o'} of length 3 or {'f','o','o','\0'} of length 4, which are considered to be interchangeable. The string is printable, does not contain non- terminating null characters, and is in an unspecified encoding (in particular, it is not guaranteed to be ASCII or UTF-8).
Quoted 6 lines
Quoted 3 lines
So it seems that these "buffer" (not "string") semantics exist there as well. Maybe it is intentional then that it is treated as a buffer rather than a string?
I'm easy. If there is a strong desire to make
SCM_SECURITYa string Smack can be changed easily enough.
Yup. I think it'd be good to have guarantees that the label can be passed to strlen(3). Whether the reported size includes the '\0' or not, that's less important, but being able to pass the buffer to strlen(3) and any other string functions is essential for safety, IMO.
Thank you very much!
Have a lovely night!
Alex
Signature · 1 line
<https://www.alejandro-colomar.es>
PATCH 5/7 man/man7/unix.7: SO_PASSSEC: wfix
In reply to Günther NoackUse "security context", as in the description of SCM_SECURITY.
--- man/man7/unix.7 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
man/man7/unix.7 +1 -1
@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the security label of the peer socket +Enables receiving of the security context of the peer socket in an ancillary message of type .B SCM_SECURITY (see below).
Signature · 1 line
2.56.0
Re: [PATCH 5/7] man/man7/unix.7: SO_PASSSEC: wfix
Quoted 14 lines · Günther Noack
Use "security context", as in the description of
SCM_SECURITY.Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>--- man/man7/unix.7 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)man/man7/unix.7 +0
-0
man/man7/unix.7 and returned as the result of · line 320
Quoted 5 lines
man/man7/unix.7 +1
-1@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the security label of the peer socket +Enables receiving of the security context of the peer socket
Patch 4 touches here, why not squash ?
Quoted 6 lines
man/man7/unix.7 +0
-0in an ancillary message of type .B SCM_SECURITY (see below).Signature · 1 line
2.56.0
Alejandro Colomar
maintainerRe: [PATCH 5/7] man/man7/unix.7: SO_PASSSEC: wfix
Hi Kuniyuki,
Quoted 13 lines
Date: 2026-10-24 05:02:06+0000
From: Kuniyuki Iwashima <[email protected]>Quoted 9 lines · Günther Noack
Use "security context", as in the description of
SCM_SECURITY.Cc Kuniyuki Iwashima <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>--- man/man7/unix.7 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
Quoted 12 lines
man/man7/unix.7 and returned as the result of · line 320
Quoted 10 lines
man/man7/unix.7 +1
-1@@ -317,7 +317,7 @@ and returned as the result of is an integer boolean flag. .TP .B SO_PASSSEC -Enables receiving of the security label of the peer socket +Enables receiving of the security context of the peer socketPatch 4 touches here, why not squash ?
I prefer not squashing. It makes the commit messages more specific, which is easier to understand and review in the future.
Have a lovely day!
Alex
Quoted 8 lines
Quoted 8 lines
man/man7/unix.7 +0
-0in an ancillary message of type .B SCM_SECURITY (see below).Signature · 1 line
2.56.0
Signature · 1 line
<https://www.alejandro-colomar.es>
Re: [PATCH 5/7] man/man7/unix.7: SO_PASSSEC: wfix
Quoted 6 lines · Alejandro Colomar
Quoted 3 lines
Date: 2026-10-24 05:02:06+0000
From: Kuniyuki Iwashima <[email protected]>
Patch 4 touches here, why not squash ?I prefer not squashing. It makes the commit messages more specific, which is easier to understand and review in the future.
Ack, leaving it unsquashed.
–Günther
Kuniyuki Iwashima
Reviewed-byRe: [PATCH 5/7] man/man7/unix.7: SO_PASSSEC: wfix
Quoted 9 lines · Günther Noack
Quoted 6 lines · Alejandro Colomar
Quoted 3 lines
Date: 2026-10-24 05:02:06+0000
From: Kuniyuki Iwashima <[email protected]>
Patch 4 touches here, why not squash ?I prefer not squashing. It makes the commit messages more specific, which is easier to understand and review in the future.
Ack, leaving it unsquashed.
Okay, then
Thanks
PATCH 6/7 man/man7/unix.7: Document SO_PASSPIDFD, SO_PEERPIDFD, and SCM_PIDFD
In reply to Günther NoackThese were added in linux.git 5e2ff6704a27 (2023-06-12; "scm: add SO_PASSPIDFD and SCM_PIDFD") and 7b26952a91cf (2023-06-12; "net: core:
add getsockopt SO_PEERPIDFD"), both in Linux 6.5. They are the PID file descriptor counterparts of SO_PASSCRED/SCM_CREDENTIALS and SO_PEERCRED.
SO_PASSPIDFD
sk_setsockopt() and sk_getsockopt() in net/core/sock.c handle it as a boolean flag for AF_UNIX sockets (EOPNOTSUPP otherwise). Like SO_PASSCRED, it triggers autobind, which was already mentioned in "Autobind feature".
SCM_PIDFD
scm_pidfd_recv() in net/core/scm.c creates the PID file descriptor from scm->pid, which is the PID given in the sender's SCM_CREDENTIALS, or the sender's own PID by default. The fd is created with O_CLOEXEC by pidfd_prepare(). If pidfd_prepare() fails, its negative error number is put into the cmsg data. Sending SCM_PIDFD is rejected by __scm_send() (EINVAL).
Since Linux 6.17, with c679d17d3f2d (2025-07-04; "af_unix:
enable handing out pidfds for reaped tasks in SCM_PIDFD"), PIDFD_STALE is passed, so this also works for reaped processes. Before that, pidfd_prepare() returned -EINVAL for them.
SO_PEERPIDFD
sk_getsockopt() returns a PID file descriptor for sk_peer_pid, or fails with ENODATA if there is none.
Since Linux 6.16, with 20b70e58961b (2025-04-28; "net, pidfs:
enable handing out pidfds for reaped sk->sk_peer_pid"), this also works for reaped processes on AF_UNIX sockets. Before that, it failed with EINVAL.
--- man/man7/unix.7 | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+)
man/man7/unix.7 +101 -0
@@ -316,6 +316,33 @@ and returned as the result of .BR getsockopt (2) is an integer boolean flag. .TP +.BR SO_PASSPIDFD " (since Linux 6.5)" +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89 +Enabling this socket option causes receipt of a PID file descriptor +(see +.BR pidfd_open (2)) +referring to the sending process in an +.B SCM_PIDFD +ancillary message in each subsequently received message +(see below). +.IP +As with +.BR SO_PASSCRED , +when this option is set on a socket that is not bound to an address, +the socket is autobound to a unique name in the abstract namespace +when +.BR connect (2) +or +.BR sendmsg (2) +is called on it; +see "Autobind feature", below. +.IP +The value given as an argument to +.BR setsockopt (2) +and returned as the result of +.BR getsockopt (2) +is an integer boolean flag. +.TP .B SO_PASSSEC Enables receiving of the security context of the peer socket in an ancillary message of type
@@ -367,6 +394,43 @@ stream and sequenced-packet sockets, and for .B AF_UNIX socket pairs created using .BR socketpair (2). +.TP +.BR SO_PEERPIDFD " (since Linux 6.5)" +.\" commit 7b26952a91cf65ff1cc867a2382a8964d8c0ee7d +This read-only socket option returns a new PID file descriptor +(see +.BR pidfd_open (2)) +referring to the peer process connected to this socket. +This is the process whose credentials are returned by +.BR SO_PEERCRED . +Unlike the PID returned by +.BR SO_PEERCRED , +the PID file descriptor cannot come to refer to a different process +if the peer process terminates and its PID is reused. +.IP +The argument to +.BR getsockopt (2) +is a pointer to an +.IR int , +in which the PID file descriptor is returned. +The close-on-exec flag +.RB ( FD_CLOEXEC ) +is set on the new file descriptor. +.IP +If the socket has no peer process, +.BR getsockopt (2) +fails with the error +.BR ENODATA . +.IP +Since Linux 6.16, +.\" commit 20b70e58961b855e61f2c6a7a19a38a64ad1bed6 +a PID file descriptor is returned +even if the peer process has already terminated and been reaped. +Before Linux 6.16, +.BR getsockopt (2) +failed with the error +.B EINVAL +in this case. .\" .SS Autobind feature If a
@@ -543,6 +607,42 @@ message, the .B SO_PASSCRED option must be enabled on the socket. .TP +.BR SCM_PIDFD " (since Linux 6.5)" +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89 +Receive a PID file descriptor +(see +.BR pidfd_open (2)) +referring to the sending process. +The data portion contains a single +.IR int . +The PID file descriptor refers to the process whose PID would be +received in an +.B SCM_CREDENTIALS +message; +if the sender specified +.B SCM_CREDENTIALS +ancillary data, +it refers to the process with the PID given there. +The close-on-exec flag +.RB ( FD_CLOEXEC ) +is set on the new file descriptor. +.IP +If the PID file descriptor cannot be created, +the data portion contains a negative error number instead. +Since Linux 6.17, +.\" commit c679d17d3f2d895b34e660673141ad250889831f +a PID file descriptor is created +even if the sending process has already terminated and been reaped. +Before Linux 6.17, +.B \-EINVAL +was received in this case. +.IP +This message cannot be sent; +it is generated by the kernel. +To receive it, the +.B SO_PASSPIDFD +option must be enabled on the socket. +.TP .B SCM_SECURITY Receive the security context (the security label) of the peer socket,
@@ -1273,6 +1373,7 @@ see and .BR seccomp_unotify (2). .SH SEE ALSO +.BR pidfd_open (2), .BR recvmsg (2), .BR sendmsg (2), .BR socket (2),
Signature · 1 line
2.56.0
Re: [PATCH 6/7] man/man7/unix.7: Document SO_PASSPIDFD, SO_PEERPIDFD, and SCM_PIDFD
Quoted 49 lines · Günther Noack
These were added in linux.git
5e2ff6704a27(2023-06-12; "scm: addSO_PASSPIDFDandSCM_PIDFD") and7b26952a91cf(2023-06-12; "net: core:
add getsockoptSO_PEERPIDFD"), both in Linux 6.5. They are the PID file descriptor counterparts of SO_PASSCRED/SCM_CREDENTIALS andSO_PEERCRED.
SO_PASSPIDFD
sk_setsockopt()andsk_getsockopt()innet/core/sock.chandle it as a boolean flag forAF_UNIXsockets (EOPNOTSUPP otherwise). LikeSO_PASSCRED, it triggers autobind, which was already mentioned in "Autobind feature".
SCM_PIDFD
scm_pidfd_recv()innet/core/scm.ccreates the PID file descriptor fromscm->pid, which is the PID given in the sender'sSCM_CREDENTIALS, or the sender's own PID by default. The fd is created withO_CLOEXECbypidfd_prepare(). Ifpidfd_prepare()fails, its negative error number is put into the cmsg data. SendingSCM_PIDFDis rejected by__scm_send()(EINVAL).Since Linux 6.17, with
c679d17d3f2d(2025-07-04; "af_unix:
enable handing out pidfds for reaped tasks inSCM_PIDFD"),PIDFD_STALEis passed, so this also works for reaped processes. Before that,pidfd_prepare()returned-EINVALfor them.
SO_PEERPIDFD
sk_getsockopt()returns a PID file descriptor forsk_peer_pid, or fails with ENODATA if there is none.Since Linux 6.16, with
20b70e58961b(2025-04-28; "net, pidfs:
enable handing out pidfds for reapedsk->sk_peer_pid"), this also works for reaped processes onAF_UNIXsockets. Before that, it failed with EINVAL.Cc Alexander Mikhalitsyn <[email protected]>Cc Christian Brauner <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Cc Eric Dumazet <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>--- man/man7/unix.7 | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+)man/man7/unix.7 +0
-0
man/man7/unix.7 and returned as the result of · line 320
Quoted 5 lines
man/man7/unix.7 +2
-0@@ -316,6 +316,33 @@ and returned as the result of .BR getsockopt (2) is an integer boolean flag. .TP +.BR SO_PASSPIDFD " (since Linux 6.5)" +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89
Why does pidfd only have SHA1 ?
Quoted 29 lines
man/man7/unix.7 +25
-0+Enabling this socket option causes receipt of a PID file descriptor +(see +.BR pidfd_open (2)) +referring to the sending process in an +.B SCM_PIDFD +ancillary message in each subsequently received message +(see below). +.IP +As with +.BR SO_PASSCRED , +when this option is set on a socket that is not bound to an address, +the socket is autobound to a unique name in the abstract namespace +when +.BR connect (2) +or +.BR sendmsg (2) +is called on it; +see "Autobind feature", below. +.IP +The value given as an argument to +.BR setsockopt (2) +and returned as the result of +.BR getsockopt (2) +is an integer boolean flag. +.TP .B SO_PASSSEC Enables receiving of the security context of the peer socket in an ancillary message of type
man/man7/unix.7 stream and sequenced-packet sockets, and for · line 403
Quoted 10 lines
man/man7/unix.7 +7
-0@@ -367,6 +394,43 @@ stream and sequenced-packet sockets, and for .B AF_UNIX socket pairs created using .BR socketpair (2). +.TP +.BR SO_PEERPIDFD " (since Linux 6.5)" +.\" commit 7b26952a91cf65ff1cc867a2382a8964d8c0ee7d +This read-only socket option returns a new PID file descriptor +(see +.BR pidfd_open (2)) +referring to the peer process connected to this socket.
Not sure if this is worth noting here, but "peer process" is a bit unclear.
For example, if process A creates socekt A, calls listen(), and pass it to process B and close()s the fd, and process C creates socket C and connects to socket A, then getsockopt(C, SO_PEERPIDFD) will return process A, not B.
Quoted 87 lines
man/man7/unix.7 +67
-0+This is the process whose credentials are returned by +.BR SO_PEERCRED . +Unlike the PID returned by +.BR SO_PEERCRED , +the PID file descriptor cannot come to refer to a different process +if the peer process terminates and its PID is reused. +.IP +The argument to +.BR getsockopt (2) +is a pointer to an +.IR int , +in which the PID file descriptor is returned. +The close-on-exec flag +.RB ( FD_CLOEXEC ) +is set on the new file descriptor. +.IP +If the socket has no peer process, +.BR getsockopt (2) +fails with the error +.BR ENODATA . +.IP +Since Linux 6.16, +.\" commit 20b70e58961b855e61f2c6a7a19a38a64ad1bed6 +a PID file descriptor is returned +even if the peer process has already terminated and been reaped. +Before Linux 6.16, +.BR getsockopt (2) +failed with the error +.B EINVAL +in this case. .\" .SS Autobind feature If a@@ -543,6 +607,42 @@ message, the .B SO_PASSCRED option must be enabled on the socket. .TP +.BR SCM_PIDFD " (since Linux 6.5)" +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89 +Receive a PID file descriptor +(see +.BR pidfd_open (2)) +referring to the sending process. +The data portion contains a single +.IR int . +The PID file descriptor refers to the process whose PID would be +received in an +.B SCM_CREDENTIALS +message; +if the sender specified +.B SCM_CREDENTIALS +ancillary data, +it refers to the process with the PID given there. +The close-on-exec flag +.RB ( FD_CLOEXEC ) +is set on the new file descriptor. +.IP +If the PID file descriptor cannot be created, +the data portion contains a negative error number instead. +Since Linux 6.17, +.\" commit c679d17d3f2d895b34e660673141ad250889831f +a PID file descriptor is created +even if the sending process has already terminated and been reaped. +Before Linux 6.17, +.B \-EINVAL +was received in this case. +.IP +This message cannot be sent; +it is generated by the kernel. +To receive it, the +.B SO_PASSPIDFD +option must be enabled on the socket. +.TP .B SCM_SECURITY Receive the security context (the security label) of the peer socket,@@ -1273,6 +1373,7 @@ see and .BR seccomp_unotify (2). .SH SEE ALSO +.BR pidfd_open (2), .BR recvmsg (2), .BR sendmsg (2), .BR socket (2),Signature · 1 line
2.56.0
Re: [PATCH 6/7] man/man7/unix.7: Document SO_PASSPIDFD, SO_PEERPIDFD, and SCM_PIDFD
Quoted 45 lines · Kuniyuki Iwashima
Quoted 44 lines · Günther Noack
These were added in linux.git
5e2ff6704a27(2023-06-12; "scm: addSO_PASSPIDFDandSCM_PIDFD") and7b26952a91cf(2023-06-12; "net: core:
add getsockoptSO_PEERPIDFD"), both in Linux 6.5. They are the PID file descriptor counterparts of SO_PASSCRED/SCM_CREDENTIALS andSO_PEERCRED.
SO_PASSPIDFD
sk_setsockopt()andsk_getsockopt()innet/core/sock.chandle it as a boolean flag forAF_UNIXsockets (EOPNOTSUPP otherwise). LikeSO_PASSCRED, it triggers autobind, which was already mentioned in "Autobind feature".
SCM_PIDFD
scm_pidfd_recv()innet/core/scm.ccreates the PID file descriptor fromscm->pid, which is the PID given in the sender'sSCM_CREDENTIALS, or the sender's own PID by default. The fd is created withO_CLOEXECbypidfd_prepare(). Ifpidfd_prepare()fails, its negative error number is put into the cmsg data. SendingSCM_PIDFDis rejected by__scm_send()(EINVAL).Since Linux 6.17, with
c679d17d3f2d(2025-07-04; "af_unix:
enable handing out pidfds for reaped tasks inSCM_PIDFD"),PIDFD_STALEis passed, so this also works for reaped processes. Before that,pidfd_prepare()returned-EINVALfor them.
SO_PEERPIDFD
sk_getsockopt()returns a PID file descriptor forsk_peer_pid, or fails with ENODATA if there is none.Since Linux 6.16, with
20b70e58961b(2025-04-28; "net, pidfs:
enable handing out pidfds for reapedsk->sk_peer_pid"), this also works for reaped processes onAF_UNIXsockets. Before that, it failed with EINVAL.Cc Alexander Mikhalitsyn <[email protected]>Cc Christian Brauner <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Cc Eric Dumazet <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>--- man/man7/unix.7 | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+)
Quoted 12 lines
man/man7/unix.7 and returned as the result of · line 320
Quoted 10 lines
man/man7/unix.7 +2
-0@@ -316,6 +316,33 @@ and returned as the result of .BR getsockopt (2) is an integer boolean flag. .TP +.BR SO_PASSPIDFD " (since Linux 6.5)" +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89Why does pidfd only have SHA1 ?
I'm removing it from the code and keeping it in the commit message, as in the other commits above.
Quoted 15 lines
man/man7/unix.7 stream and sequenced-packet sockets, and for · line 403
Quoted 11 lines
man/man7/unix.7 +7
-0@@ -367,6 +394,43 @@ stream and sequenced-packet sockets, and for .B AF_UNIX socket pairs created using .BR socketpair (2). +.TP +.BR SO_PEERPIDFD " (since Linux 6.5)" +.\" commit 7b26952a91cf65ff1cc867a2382a8964d8c0ee7d +This read-only socket option returns a new PID file descriptor +(see +.BR pidfd_open (2)) +referring to the peer process connected to this socket.Not sure if this is worth noting here, but "peer process" is a bit unclear.
Quoted 4 lines
For example, if process A creates socekt A, calls
listen(), and pass it to process B and close()s the fd, and process C creates socket C and connects to socket A, thengetsockopt(C, SO_PEERPIDFD)will return process A, not B.
I think it is OK; The phrase "peer process connected to this socket" is adapted from the description of SO_PEERCRED, and to clarify, the next sentence refers to the description of SO_PEERCRED in the same file:
Quoted 2 lines
man/man7/unix.7 stream and sequenced-packet sockets, and for · line 405
Quoted 2 lines
man/man7/unix.7 +2
-0+This is the process whose credentials are returned by +.BR SO_PEERCRED .
^ Here
I think the SO_PEERCRED description is good:
This read-only socket option returns the credentials of the peer process connected to this socket. The returned credentials are those that were in effect at the time of the call to connect(2), listen(2) or sockepair(2).
(It is good, because it puts the common use case first, where the entire BSD socket dance is done by the same process, and then clarifies the details for the people who need them.)
So this seems fair to me, imho. Let me know whether that seems acceptable to you.
–Günther
Re: [PATCH 6/7] man/man7/unix.7: Document SO_PASSPIDFD, SO_PEERPIDFD, and SCM_PIDFD
Quoted 100 lines · Günther Noack
Quoted 45 lines · Kuniyuki Iwashima
Quoted 44 lines · Günther Noack
These were added in linux.git
5e2ff6704a27(2023-06-12; "scm: addSO_PASSPIDFDandSCM_PIDFD") and7b26952a91cf(2023-06-12; "net: core:
add getsockoptSO_PEERPIDFD"), both in Linux 6.5. They are the PID file descriptor counterparts of SO_PASSCRED/SCM_CREDENTIALS andSO_PEERCRED.
SO_PASSPIDFD
sk_setsockopt()andsk_getsockopt()innet/core/sock.chandle it as a boolean flag forAF_UNIXsockets (EOPNOTSUPP otherwise). LikeSO_PASSCRED, it triggers autobind, which was already mentioned in "Autobind feature".
SCM_PIDFD
scm_pidfd_recv()innet/core/scm.ccreates the PID file descriptor fromscm->pid, which is the PID given in the sender'sSCM_CREDENTIALS, or the sender's own PID by default. The fd is created withO_CLOEXECbypidfd_prepare(). Ifpidfd_prepare()fails, its negative error number is put into the cmsg data. SendingSCM_PIDFDis rejected by__scm_send()(EINVAL).Since Linux 6.17, with
c679d17d3f2d(2025-07-04; "af_unix:
enable handing out pidfds for reaped tasks inSCM_PIDFD"),PIDFD_STALEis passed, so this also works for reaped processes. Before that,pidfd_prepare()returned-EINVALfor them.
SO_PEERPIDFD
sk_getsockopt()returns a PID file descriptor forsk_peer_pid, or fails with ENODATA if there is none.Since Linux 6.16, with
20b70e58961b(2025-04-28; "net, pidfs:
enable handing out pidfds for reapedsk->sk_peer_pid"), this also works for reaped processes onAF_UNIXsockets. Before that, it failed with EINVAL.Cc Alexander Mikhalitsyn <[email protected]>Cc Christian Brauner <[email protected]>Cc Kuniyuki Iwashima <[email protected]>Cc Eric Dumazet <[email protected]>Assisted-by LLMSigned-off-by Günther Noack <[email protected]>--- man/man7/unix.7 | 101 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+)Quoted 12 lines
man/man7/unix.7 and returned as the result of · line 320
Quoted 10 lines
man/man7/unix.7 +2
-0@@ -316,6 +316,33 @@ and returned as the result of .BR getsockopt (2) is an integer boolean flag. .TP +.BR SO_PASSPIDFD " (since Linux 6.5)" +.\" commit 5e2ff6704a275be009be8979af17c52361b79b89Why does pidfd only have SHA1 ?
I'm removing it from the code and keeping it in the commit message, as in the other commits above.
Quoted 15 lines
man/man7/unix.7 stream and sequenced-packet sockets, and for · line 403
Quoted 11 lines
man/man7/unix.7 +7
-0@@ -367,6 +394,43 @@ stream and sequenced-packet sockets, and for .B AF_UNIX socket pairs created using .BR socketpair (2). +.TP +.BR SO_PEERPIDFD " (since Linux 6.5)" +.\" commit 7b26952a91cf65ff1cc867a2382a8964d8c0ee7d +This read-only socket option returns a new PID file descriptor +(see +.BR pidfd_open (2)) +referring to the peer process connected to this socket.Not sure if this is worth noting here, but "peer process" is a bit unclear.
Quoted 4 lines
For example, if process A creates socekt A, calls
listen(), and pass it to process B and close()s the fd, and process C creates socket C and connects to socket A, thengetsockopt(C, SO_PEERPIDFD)will return process A, not B.I think it is OK; The phrase "peer process connected to this socket" is adapted from the description of
SO_PEERCRED, and to clarify, the next sentence refers to the description ofSO_PEERCREDin the same file:Quoted 2 lines
man/man7/unix.7 stream and sequenced-packet sockets, and for · line 405
Quoted 2 lines
man/man7/unix.7 +2
-0+This is the process whose credentials are returned by +.BR SO_PEERCRED .^ Here
I think the
SO_PEERCREDdescription is good:This read-only socket option returns the credentials of the peer process connected to this socket. The returned credentials are those that were in effect at the time of the call to connect(2), listen(2) or sockepair(2).
Quoted 6 lines
(It is good, because it puts the common use case first, where the entire BSD socket dance is done by the same process, and then clarifies the details for the people who need them.)
So this seems fair to me, imho. Let me know whether that seems acceptable to you.
Probably okay as is. Maybe not many people is using socket activation w/ systemd.
PATCH 7/7 man/man7/unix.7: Document SO_PASSRIGHTS
In reply to Günther NoackSO_PASSRIGHTS was added in linux.git 77cbe1a6d873 (2025-05-23; "af_unix: Introduce SO_PASSRIGHTS."), in Linux 6.16. It lets a receiver refuse file descriptors passed with SCM_RIGHTS, so that an untrusted peer cannot leave it with file descriptors whose final close() blocks for a long time (for example, a file on a hung NFS mount or a FUSE-controlled file).
The option is enabled by default (unix_create1()). When the receiving socket has it disabled, unix_dgram_sendmsg(), unix_stream_sendmsg(), and queue_oob() fail with EPERM if the message carries file descriptors. The check happens at send time, so messages that are already queued are unaffected.
Also add the new EPERM case to ERRORS.
--- man/man7/unix.7 | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)
man/man7/unix.7 +37 -0
@@ -343,6 +343,35 @@ and returned as the result of .BR getsockopt (2) is an integer boolean flag. .TP +.BR SO_PASSRIGHTS " (since Linux 6.16)" +.\" commit 77cbe1a6d8730a07f99f9263c2d5f2304cf5e830 +This socket option controls whether the socket accepts +file descriptors from its peers in +.B SCM_RIGHTS +ancillary messages (see below). +It is enabled by default. +When it is disabled, +.BR sendmsg (2) +calls that pass file descriptors to this socket +fail with the error +.BR EPERM . +The option is checked when the message is sent; +disabling it does not affect messages +that are already queued on the socket. +.IP +Processes that do not expect to receive file descriptors +can disable this option. +Once the file descriptors have been passed, +closing them is the responsibility of the receiving process, +and this may block for a long time, +for example for a file on an unresponsive network file system. +.IP +The value given as an argument to +.BR setsockopt (2) +and returned as the result of +.BR getsockopt (2) +is an integer boolean flag. +.TP .B SO_PASSSEC Enables receiving of the security context of the peer socket in an ancillary message of type
@@ -893,6 +922,14 @@ or specified a datagram socket as the remote address, but that socket is connected to a different socket. .TP +.B EPERM +The sender passed file descriptors in an +.B SCM_RIGHTS +ancillary message, +but the receiving socket has the +.B SO_PASSRIGHTS +option disabled. +.TP .B EPIPE Remote socket was closed on a stream socket. If enabled, a
Signature · 1 line
2.56.0