|Anonymous | Login||2023-12-01 07:40 UTC|
|Main | My View | View Issues | Change Log | Docs|
|Viewing Issue Simple Details|
|ID||Category||Severity||Type||Date Submitted||Last Update|
|0000561||[1003.1(2008)/Issue 7] System Interfaces||Objection||Error||2012-05-03 16:14||2023-01-17 11:52|
|Priority||normal||Resolution||Accepted As Marked|
|Final Accepted Text||Note: 0006085|
|Summary||0000561: NUL-termination of sun_path in Unix sockets|
Several messages on the mail reflector pointed out some issues with Unix
sockets, as provided by <sys/un.h>.
The standard is ambiguous whether a Unix socket filename when passed through
and interface such as getsockname with a too-small size will guarantee NUL
termination of the resulting output; however, many existing applications
assume the presence of a NUL terminator, and may misbehave if one is not
guaranteed. Furthermore, all implementations currently implement sun_path
as the last member of struct sockaddr_un, but without a guarantee, it is
not possible to provide an input structure larger than sockaddr_un in order
to guarantee NUL termination if all bytes of sun_path are allowed to be
Other issues include the fact that POSIX 1003.1g defined a macro SUN_LEN
to help in computing the length of a socket name, but this macro was
not incorporated into POSIX 2008.
Additional requirements need to be added to specify the treatment of all
socket families that bind to a filename. The wording is still a work in
progress, and will be added as a note later; for now, this defect serves
as a placeholder to identify the issue.
As stated on the mailing list, OpenBSD's solution to this issue was to require space for the NUL terminator in sun_path. Applications that always use sockaddr_un for UNIX socket addresses are then guaranteed that sun_path will be NUL terminated.
Since POSIX doesn't guarantee sun_path will be of any particular size anyway, this shouldn't be a compatibility issue.
Actually, the older POSIX 1003.1g requires sun_path to be at least 100 bytes
(that would imply sun_path of 101 bytes if you require a NUL); although the
current non-normative wording in <sys/un.h> states that sun_path might be as
small as 92 bytes. Does anyone have an example system where sun_path was
less than 100 bytes?
It's not enough to ensure a NUL pointer in sun_path on creation; you must
also consider the guarantees of a NUL pointer on output via functions like
getsockname(), even if the length parameter passed to getsockname() was
smaller than sizeof(struct sockaddr_un).
Our guarantee is that userland apps that use a sockaddr_un for receiving a UNIX socket address via getsockname()/etc will have a NUL terminator. We don't make any NUL termination guarantees if userland allocates less than sizeof(struct sockaddr_un) bytes.
Is it necessary that if a user tries to call getsockname() on a PF_UNIX socket with a sockaddr_in or sockaddr_in6 that the path returned to userspace still be NUL terminated? Why? Userspace can detect when the path was truncated by comparing the returned *socklen or sa_len with the amount of space they allocated. Because currently sun_path isn't guaranteed to be at the end of the sockaddr, a truncated sockaddr has no guaranteed meaning.
|HP-UX has a 92-byte limit on sun_path.|
edited on: 2023-01-09 16:50
Page and line numbers are for Issue 8 draft 2.1.
At page 403 line 13894 section <sys/un.h> DESCRIPTION, change:
<tt>char sun_path</tt> Socket pathname.
<tt>char sun_path[size]</tt> Socket pathname storage.
At page 403 line 13899 section <sys/un.h> APPLICATION USAGE, change:
The size of sun_path has intentionally been left undefined. This is because different implementations use different sizes. For example, 4.3 BSD uses a size of 108, and 4.4 BSD uses a size of 104. Since most implementations originate from BSD versions, the size is typically in the range 92 to 108.
The size of sun_path is required to be constant, but intentionally does not have a specified name for that constant. Historically, different implementations used different sizes. For example, 4.3 BSD used a size of 108, and 4.4 BSD used a size of 104. Since most implementations originate from BSD versions, the size is typically in the range 92 to 108. An application can deduce the size by using <tt>sizeof(((struct sockaddr_un *)0)->sun_path)</tt>.
At page 403 line 13911 section <sys/un.h> RATIONALE, change from "None" to:
Some implementations expose a macro <tt>SUN_LEN</tt> for the size of a pathname stored in <tt>sun_path</tt>. However, this was not widely adopted, and differences on how a terminating NUL byte is interpreted between implementations did not make it worth standardizing.
After page 543 line 19233 section accept() and
page 1745 line 57250 section recvfrom(), add to APPLICATION USAGE,
and at page 1055 line 36136 section getpeername() and
page 1081 line 36940 section getsockname(), change APPLICATION USAGE from "None" to:
For AF_UNIX sockets, it is recommended that address points to a buffer of length greater than <tt>sizeof(struct sockaddr_un)</tt> which has been initialized with null bytes. That way, even if the implementation supports the use of all bytes of sun_path without a terminating null byte, the larger buffer guarantees that the sun_path member can then be passed to other interfaces that expect a null-terminated string. If no truncation occurred based on the input value of address_len, It is unspecified whether the returned address_len will be <tt>sizeof(struct sockaddr_un)</tt>, or merely a value at least as large as <tt>offsetof(struct sockaddr_un, sun_path)</tt> plus the number of non-null bytes stored in sun_path.
At page 604 line 21124 section bind() DESCRIPTION, after applying bug 1605 change:
If the address family of the socket is AF_UNIX and the pathname in address names an existing file, including a symbolic link, bind() shall treat the address as already in use; see ERRORS below.
If the address family of the socket is AF_UNIX, the application shall ensure that a null terminator after the pathname is included in the sun_path member of address as a sockaddr_un structure, and that address_len is at least <tt>offsetof(struct sockaddr_un, sun_path) + 1</tt> plus the length of the pathname. If the pathname in the sun_path member of address names an existing file, including a symbolic link, bind( ) shall treat the address as already in use; see ERRORS below.
After page 606 line 21209 section bind() add to APPLICATION USAGE,
and after page 686 line 23737 section connect() add to APPLICATION USAGE:
For AF_UNIX sockets, some implementations support an extension where address_len does not have to include a null terminator for the pathname stored in sun_path, which in turn allows a pathname to be one byte longer. However, such usage is not portable, and carries a risk of accessing beyond the intended bounds of the pathname length.
After page 684 line 23647 section connect() add to DESCRIPTION:
If the address family of the socket is AF_UNIX, the application shall ensure that a null terminator after the pathname is included in the sun_path member of address as a sockaddr_un structure, and that address_len is at least <tt>offsetof(struct sockaddr_un, sun_path) + 1</tt> plus the length of the pathname.
After page 1836 line 60177 section sendto() add to DESCRIPTION:
If the address family of the socket is AF_UNIX, the application shall ensure that a null terminator after the pathname is included in the sun_path member of dest_addr as a sockaddr_un structure, and that dest_len is at least <tt>offsetof(struct sockaddr_un, sun_path) + 1</tt> plus the length of the pathname.
After page 1838 line 60255 section sendto() add to APPLICATION USAGE:
For AF_UNIX sockets, some implementations support an extension where dest_len does not have to include a null terminator for the pathname stored in sun_path, which in turn allows a pathname to be one byte longer. However, such usage is not portable, and carries a risk of accessing beyond the intended bounds of the pathname length.
|In the Jan 9, 2023 teleconference, Note: 0006085 was updated to use sizeof(((struct sockaddr_un *)0)->sun_path) in the <sys/un.h> APPLICATION USAGE instead of subtracting offsetof(...) from the size of the structure.|
|2012-05-03 16:14||eblake||New Issue|
|2012-05-03 16:14||eblake||Status||New => Under Review|
|2012-05-03 16:14||eblake||Assigned To||=> ajosey|
|2012-05-03 16:14||eblake||Name||=> Eric Blake|
|2012-05-03 16:14||eblake||Organization||=> Red Hat|
|2012-05-03 16:14||eblake||User Reference||=> ebb.sockaddr_un|
|2012-05-03 16:14||eblake||Section||=> <sys/un.h>|
|2012-05-03 16:14||eblake||Page Number||=> 403|
|2012-05-03 16:14||eblake||Line Number||=> 13515|
|2012-05-03 16:14||eblake||Interp Status||=> ---|
|2012-05-03 17:23||mdempsky||Note Added: 0001226|
|2012-05-03 17:33||eblake||Note Added: 0001227|
|2012-05-03 17:39||mdempsky||Note Added: 0001228|
|2012-05-04 22:21||mkerrisk||Note Added: 0001233|
|2012-06-04 14:15||codonell||Issue Monitored: codonell|
|2022-07-20 20:34||eblake||Relationship added||related to 0001593|
|2022-11-28 16:24||geoffclare||Note Added: 0006085|
|2022-11-28 16:26||geoffclare||Final Accepted Text||=> Note: 0006085|
|2022-11-28 16:26||geoffclare||Status||Under Review => Resolved|
|2022-11-28 16:26||geoffclare||Resolution||Open => Accepted As Marked|
|2022-11-28 16:27||geoffclare||Tag Attached: issue8|
|2023-01-09 16:50||geoffclare||Note Edited: 0006085|
|2023-01-09 16:52||geoffclare||Note Added: 0006102|
|2023-01-09 16:56||Don Cragun||Relationship replaced||has duplicate 0001593|
|2023-01-17 11:52||geoffclare||Status||Resolved => Applied|
|Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group|