public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
From: Eric Blake <eblake@redhat.com>
To: Alejandro Colomar <alx.manpages@gmail.com>
Cc: linux-man@vger.kernel.org, "Alejandro Colomar" <alx@kernel.org>,
	"Bastien Roucariès" <rouca@debian.org>,
	glibc <libc-alpha@sourceware.org>, GCC <gcc@gcc.gnu.org>,
	"Stefan Puiu" <stefan.puiu@gmail.com>,
	"Igor Sysoev" <igor@sysoev.ru>, "Rich Felker" <dalias@libc.org>,
	"Andrew Clayton" <andrew@digital-domain.net>,
	"Richard Biener" <richard.guenther@gmail.com>,
	"Zack Weinberg" <zack@owlfolio.org>,
	"Florian Weimer" <fweimer@redhat.com>,
	"Joseph Myers" <joseph@codesourcery.com>,
	"Jakub Jelinek" <jakub@redhat.com>, "Sam James" <sam@gentoo.org>
Subject: Re: [PATCH] sockaddr.3type: Document that sockaddr_storage is the API to be used
Date: Thu, 30 Mar 2023 14:11:12 -0500	[thread overview]
Message-ID: <ga44kb7s2atbgl6exbjvpffp6czurhxff4nxf7ugflyfpjhlb5@pvwnm2udgso5> (raw)
In-Reply-To: <20230330171310.12330-1-alx@kernel.org>

On Thu, Mar 30, 2023 at 07:13:11PM +0200, Alejandro Colomar wrote:
> POSIX.1 Issue 8 will fix the long-standing issue with sockaddr APIs,
> which inevitably caused UB either on user code, libc, or more likely,
> both.  sockaddr_storage has been clarified to be implemented in a manner
> that aliasing it is safe (suggesting a unnamed union, or other compiler
> magic).
> 
> Link: <https://www.austingroupbugs.net/view.php?id=1641>
> Reported-by: Bastien Roucariès <rouca@debian.org>
> Reported-by: Alejandro Colomar <alx@kernel.org>
> Cc: glibc <libc-alpha@sourceware.org>
> Cc: GCC <gcc@gcc.gnu.org>
> Cc: Eric Blake <eblake@redhat.com>
> Cc: Stefan Puiu <stefan.puiu@gmail.com>
> Cc: Igor Sysoev <igor@sysoev.ru>
> Cc: Rich Felker <dalias@libc.org>
> Cc: Andrew Clayton <andrew@digital-domain.net>
> Cc: Richard Biener <richard.guenther@gmail.com>
> Cc: Zack Weinberg <zack@owlfolio.org>
> Cc: Florian Weimer <fweimer@redhat.com>
> Cc: Joseph Myers <joseph@codesourcery.com>
> Cc: Jakub Jelinek <jakub@redhat.com>
> Cc: Sam James <sam@gentoo.org>
> Signed-off-by: Alejandro Colomar <alx@kernel.org>
> ---
> 
> Hi all,
> 
> This is my proposal for documenting the POSIX decission of fixing the
> definition of sockaddr_storage.  Bastien, I believe you had something
> similar in mind; please review.  Eric, thanks again for the fix!  Could
> you please also have a look at this?
> 
> Cheers,
> 
> Alex
> 
>  man3type/sockaddr.3type | 22 ++++++++++++++++++++++
>  1 file changed, 22 insertions(+)
> 
> diff --git a/man3type/sockaddr.3type b/man3type/sockaddr.3type
> index 32c3c5bd0..d1db87d5d 100644
> --- a/man3type/sockaddr.3type
> +++ b/man3type/sockaddr.3type
> @@ -23,6 +23,14 @@ .SH SYNOPSIS
>  .PP
>  .B struct sockaddr_storage {
>  .BR "    sa_family_t     ss_family;" "      /* Address family */"
> +.PP
> +.RS 4
> +/* This structure is not really implemented this way.  It may be
> +\&   implemented with an unnamed union or some compiler magic to
> +\&   avoid breaking aliasing rules when accessed as any other of the
> +\&   sockaddr_* structures documented in this page.  See CAVEATS.
> +\& */

Do we want similar comments in struct sockaddr and/or sockaddr_XX?

> +.RE
>  .B };
>  .PP
>  .BR typedef " /* ... */ " socklen_t;
> @@ -122,6 +130,20 @@ .SH NOTES
>  .I <netinet/in.h>
>  and
>  .IR <sys/un.h> .
> +.SH CAVEATS
> +To avoid breaking aliasing rules,
> +programs that use functions that receive pointers to
> +.I sockaddr
> +structures should declare objects of type
> +.IR sockaddr_storage ,
> +which is defined in a way that it
> +can be accessed as any of the different structures defined in this page.
> +Failure to do so may result in Undefined Behavior.

Existing POSIX already requires sockaddr_storage to be suitably sized
and aligned to overlay with all other sockaddr* types.  What the
recent POSIX bug change does is add wording to emphasize that casts in
any of the 6 directions:

sockaddr* <-> sockaddr_XX*
sockaddr_storage* <-> sockaddr*
sockaddr_storage* <-> sockaddr_XX*

must allow the sa_family/ss_family/sa_family_t member to overlay
without triggering undefined behavior due to bad aliasing, at which
point, access to that member lets you deduce what other object type
you really have.  But you are also correct that merely casting a
pointer to another larger struct that doesn't trigger aliasing, but
then dereferencing beyond the bounds of the original, is not intended
to be portable.  The aliasing diagnostics are suppressed because of
the requirements on the first member, so now the user must now be
careful that their access of remaining members is safe even if the
compiler is no longer helping them because of the magic that
suppressed the aliasing detection.

I agree with your warning that code that can handle generic socket
types should use sockaddr_storage (and not sockaddr) as the original
object (the one object that the standard requires to be suitably sized
and aligned to overlay with the entirety of all other sockaddr types,
rather than just the sa_family_t first member), although we may want
to be more precise that code using a specific protocol type can
directly use the proper sockaddr_XX type rather than having to use an
intermediate sockaddr_storage.

I'm not sure if there are better ways to word that paragraph to convey
the intended sentiment.

> +.PP
> +New functions should be written to accept pointers to
> +.I sockaddr_storage
> +instead of the traditional
> +.IR sockaddr .

I'm less certain about this one.  The POSIX wording specifically chose
to keep existing API/ABI of sockaddr* in all the standardized
functions unchanged, as it would be too invasive to existing code to
change the signatures now.  The burden is on the system headers to
define types so that the necessary casts (present in lots of existing
code because sockaddr* has a bit more type-safety than void*) do not
of themselves cause aliasing issues, and therefore avoid undefined
behavior provided subsequent code accessing through the pointers is
not accessing beyond the bounds of the real object.  The likelihood of
POSIX adding new socket APIs taking sockaddr_storage* just to enforce
non-aliasing seems slim.  But then again, this advice applies to more
than just functions likely to be standardized in a future libc, so
maybe this paragraph is worth it after all.

>  .SH SEE ALSO
>  .BR accept (2),
>  .BR bind (2),
> -- 
> 2.39.2
> 

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org


  reply	other threads:[~2023-03-30 19:11 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-30 17:13 Alejandro Colomar
2023-03-30 19:11 ` Eric Blake [this message]
2023-04-05  0:42   ` Alejandro Colomar
2023-04-06 16:24     ` Eric Blake
2023-04-06 16:31       ` Alejandro Colomar
2023-04-06 18:05         ` Zack Weinberg
2023-04-06 19:37           ` Eric Blake
2023-04-14 16:08             ` Zack Weinberg
2023-04-21 14:58               ` Alejandro Colomar
2023-04-21 15:00                 ` Alejandro Colomar
2023-04-21 15:27                   ` Eric Blake
2023-04-21 20:27                     ` [PATCH v3] sockaddr.3type: POSIX Issue 8 will solve strict-aliasing issues with these types Alejandro Colomar
2023-04-21 20:35                       ` Eric Blake

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ga44kb7s2atbgl6exbjvpffp6czurhxff4nxf7ugflyfpjhlb5@pvwnm2udgso5 \
    --to=eblake@redhat.com \
    --cc=alx.manpages@gmail.com \
    --cc=alx@kernel.org \
    --cc=andrew@digital-domain.net \
    --cc=dalias@libc.org \
    --cc=fweimer@redhat.com \
    --cc=gcc@gcc.gnu.org \
    --cc=igor@sysoev.ru \
    --cc=jakub@redhat.com \
    --cc=joseph@codesourcery.com \
    --cc=libc-alpha@sourceware.org \
    --cc=linux-man@vger.kernel.org \
    --cc=richard.guenther@gmail.com \
    --cc=rouca@debian.org \
    --cc=sam@gentoo.org \
    --cc=stefan.puiu@gmail.com \
    --cc=zack@owlfolio.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).