Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0001641 [1003.1(2016/18)/Issue7+TC2] System Interfaces Editorial Clarification Requested 2023-03-18 07:52 2024-06-11 09:07
Reporter bastien View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Closed  
Name Bastien Roucaries
Organization debian
User Reference
Section sys/socket.h
Page Number Application usage
Line Number sockaddr_storage
Interp Status Approved
Final Accepted Text see Note: 0006290
Summary 0001641: sockaddr_storage is not alias safe
Description  sockaddr_storage was designed back when strict aliasing wasn’t a problem.

 Back then, one would define a variable of that type, and then access it as any of the other sockaddr_* types, depending on the value of the first member. This is Undefined Behavior.

However, there is no
way to use these APIs without invoking Undedfined Behavior, either in
the user program or in libc, so it is still recommended to use this
method. The only correct way to use different types in an API is
through a union.

Exemple of safe use
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/un.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <stddef.h>

union sockaddr_mayalias {
  sa_family_t ss_family;
  struct sockaddr sock;
  struct sockaddr_storage storage;
  struct sockaddr_in in;
  struct sockaddr_in6 in6;
  struct sockaddr_un un;
};
  
int main() {
  union sockaddr_mayalias sa = {};
  socklen_t addrlen = sizeof(sa);
  if(getsockname(STDIN_FILENO, &sa.sock, &addrlen) < 0) {
    perror("getsockname");
    return 1;
  }
  if(addrlen >= sizeof(sa)) {
    errno = EPROTONOSUPPORT;
    perror("getsockname return a not supported sock_addr");
    return 1;
  }
  
  switch(sa.ss_family) {
  case(AF_UNSPEC):
    printf("AF_UNSPEC socket\n");
    break;
  case(AF_INET):
    {
      char s[INET_ADDRSTRLEN];
      in_port_t port = ntohs(sa.in.sin_port);
      if (inet_ntop(AF_INET, &(sa.in.sin_addr), s, sizeof(s)) == NULL) {
    perror("inet_ntop");
    return 1;
      }
      printf("AF_INET socket %s:%i\n",s,(int)port);
      break;
    }
  case(AF_INET6):
    {
      char s[INET6_ADDRSTRLEN];
      in_port_t port = ntohs(sa.in6.sin6_port);
      if (inet_ntop(AF_INET6, &(sa.in6.sin6_addr), s, sizeof(s)) == NULL) {
    perror("inet_ntop");
    return 1;
      }
      printf("AF_INET6 socket %s:%i\n",s,(int)port);
      break;
    }
  case(AF_UNIX):
    if(addrlen == sizeof(sa_family_t)) {
      printf("AF_UNIX socket anonymous\n");
      break;
    }
    /* abstract */
    if(sa.un.sun_path[0]=='\0') {
      printf("AF_UNIX abstract socket 0x");
      for (int i = 0; i < (addrlen - sizeof(sa_family_t)); ++i)
    printf("%x",sa.un.sun_path[i]);
      printf("\n");
      break;
    }
    /* named */
    printf("AF_UNIX named socket ");
    for (int i=0; i < strnlen(sa.un.sun_path, addrlen - offsetof(struct sockaddr_un, sun_path));++i)
      printf("%c",sa.un.sun_path[i]);
    printf("\n");
    break;
  default:
      errno = EPROTONOSUPPORT;
      perror("socket not supported");
      return 1;
}

    
}
Desired Action 1. document aliasing problem
2. define sockaddr storage as:
struct sockaddr_storage {
        union {
                sa_family_t ss_family;
                struct sockaddr sa;
                struct sockaddr_in sin;
                struct sockaddr_in6 sin6;
                struct sockaddr_un sun;
                struct _sockaddr_padding padding;
        };
};
Tags applied_after_i8d3, tc3-2008
Attached Files

- Relationships

-  Notes
(0006207)
bastien (reporter)
2023-03-18 07:53

Please note that function that pass sockaddr * instead of void may suffer of the same aliasing problem
(0006208)
wlerch (reporter)
2023-03-20 13:20

A general note: just because C considers something undefined behaviour does not mean that POSIX can't define it. For example, using dlsym() to return a pointer to a function involves a conversion that C considers undefined, but POSIX requires it to work. It just means that POSIX specifies some additional requirements on compilers that C does not.

Of course, it is probably a good idea to try to keep such additional requirements to a minimum, and mention them explicitly, like the dlsym() page does.
(0006209)
bastien (reporter)
2023-03-20 13:38

yes I should be documented at least.

Using a __attribute__((__may_alias__)) for the struct attribute will help here, but it is I think simpler to use the plan 2 that is safe and backward compatible.

For the *sockaddr problem for int getpeername, I do not know the safe path.

transparent_union is a solution but it is not always implemented.
(0006211)
steffen (reporter)
2023-03-20 23:06

The famous Dennis Ritchie 7753@alice.UUCP quote from Article 7844 of comp.lang.c:
 
 The fundamental problem is that it is not possible to write real programs using the X3J11 definition of C. The committee has created an unreal language that no one can or will actually use.

Also the July 15, 2019 LWN.net "Who's afraid of a big bad optimizing compiler?"

Other than that ISO C99 does not know about unnamed unions.
ISO C89 that i comply to as far as possible (a hundred percent with the help of some support macros) also does not.

  (Not to mention that terrible tremendous breath-taking gcc (g++) 3.4.2 bug which did not like unnamed unions and caused real pain on my side.)
(0006212)
hvd (reporter)
2023-03-21 12:01

Re Note: 0006211: That famous quote is about something that was proposed to be part of the standard but ended up being removed before C90 and is not part of any version of the C standard. The sentence that follows that quote would have made that beyond obvious. I highly suspect you are well aware of this and left out that following sentence deliberately.
(0006215)
sam_james (reporter)
2023-03-21 23:09

This was discussed extensively recently on the libc-alpha and gcc mailing lists at https://sourceware.org/pipermail/libc-alpha/2023-February/145304.html [^] which was the motivation for this defect report.
(0006216)
steffen (reporter)
2023-03-21 23:33

I'd very much prefer if there would be an exception like there is one for dlsym, like wlerch has shown in #0006208.

Anything else seems to be a road to madness, as sockaddr_storage is required by the standard (and by real life, mind you) to be correctly aligned for any other socket address type, and then you should be able to cast -- _without_ going over an intermediate (char*), or (char*)(void*), or whatever they want to be done .. to get it done.

Anyway this issue is opened against the wrong standard, because this POSIX bases upon ISO C99, and ISO C99 does not support unnamed unions. Voila.


P.S.: since my C can be compiled with C++ i am still frustrated after more than two decades to have the necessity to use C-style casts to assign to some "virtual table" function pointers, instead of even reinterpret_cast<>.
You know, if i have xy_clone() i want and need to assign it to (*y_clone), and i do so for almost the quarter of a century, and it works. (I assign a function pointer, though mismatch -- the generic vtbl uses void*, say.)
Now compilers complain on the use of "old-style" casts, and i am afraid someday they close the door without replacement. Then i stop flying over that coockoo thing.
Just my one cent.
(0006217)
bastien (reporter)
2023-03-22 09:42

@steffen do not supporting aliasing in general will be no way from compiler folk...

And it is not the wrong standard, the problem is for historical reason socket API pass struct sockaddr* and not void *.

Using void * will have avoided this issue.

the __attribute__((__may_alias__)) is a common C extension and will solve this problem.

Transparent union is also a common supported extension.

May be a safe path will be:
1. Prefered option struct sockaddr and struct sockaddr_storage may alias other structure
2. If compiler does not support this common extension, aliasing should be disabled
(0006227)
steffen (reporter)
2023-03-22 21:56

No. "Issue 8 drafts" is maybe the right standard.

I say maybe. I personally am the wrong person to talk to, i hate this aliasing issue, i saw so-and-so many *BSD and more commits fly by where code that worked started breaking, and had to be circumvented by doing memcpy(), sheer grazy.

They _broke_ the system. And i am yet to see the advantages. (From my simple userspace programmer's point of view, with a bit of assembler, in earlier times.)
So if an intermediate cast to "char*" gets you going, or "void*", why do that at all?
It _will_ fit in the size of sockaddr_storage, it will have the proper alignment, i want to cast it. Period.

"POSIX-compliant compilers" (-std=c99) should not fail in theory.
Issue 7 is based upon ISO C99.
(0006238)
eblake (manager)
2023-03-30 15:20

On page 386 line 13115 section <sys/socket.h> DESCRIPTION, change:
When a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family.
to:
When a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, or vice versa, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, or vice versa, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family. When a pointer to a sockaddr structure is cast as a pointer to a protocol-specific address structure, or vice versa, the sa_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family. Additionally, the structures shall be defined in such a way that these casts do not cause the compiler to produce diagnostics about aliasing issues when compiling conforming application (xref to XBD section 2.2) source files.


On page 390 line 13260 section <sys/socket.h> APPLICATION USAGE, append a sentence:
Note that this example only deals with size and alignment; see RATIONALE for additional issues related to these structures.


On page 390 line 13291 section <sys/socket.h>, change RATIONALE from "None" to:
Note that defining the sockaddr_storage and sockaddr structures using only mechanisms defined in editions of the ISO C standard prior to the 2011 edition (C11) may produce aliasing diagnostics when used in C11 and later editions of the ISO C standard. Because of the large body of existing code utilizing sockets in a way that was well-defined in the 1999 edition of the ISO C standard (C99) but could trigger undefined behavior if C11/C17 aliasing detection were enforced, this standard mandates that casts between pointers to the various socket address structures do not produce aliasing diagnostics, so as to preserve well-defined semantics. An implementation's header files may need to use anonymous unions, or even an implementation-specific extension such as a <tt>[[__may_alias__]]</tt> attribute, to comply with the requirements of this standard.
(0006249)
eblake (manager)
2023-04-03 16:36

Reopened during the 2023-04-03 meeting; Note: 0006238 may not be sufficiently precise in its wording (both C99 and C11 section 6.5 paragraph 7 have similar wording on undefined behavior when dereferencing an lvalue of a type not compatible with the effective type of the underlying storage, so claiming that aliasing warnings were only introduced in C11 is wrong). The Austin Group is still working on alternative wording ideas, but consensus from today is that an interpretation request will be needed, along the lines of:

The standard clearly states that when a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure maps onto the sa_family field of the sockaddr structure and when a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field maps onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family, and conforming implementations must conform to this.

Rationale:
-------------
In stating these field mapping requirements when a cast operator is applied to the various socket address structures, the standard defines the behavior in circumstances where the behavior is undefined in the ISO C standard. The onus is on implementations to ensure that these mappings are as described in the standard, making use of implementation-specific extensions if necessary, even though this is not stated explicitly.
(0006253)
steffen (reporter)
2023-04-03 22:42

hmm. 0006249:

 (both C99 and C11 section 6.5 paragraph 7 have similar wording on undefined behavior..

C99, 6.3.2.3 Pointers, paragraph 7:

  A pointer to an object [.] may be converted to a pointer to a different object [.] type. If the resulting pointer is not correctly aligned[57] for the pointed-to type, the behavior is undefined.

And footnote [57] says (even)

  In general,
(0006254)
steffen (reporter)
2023-04-03 22:44

oh. i hate web interfaces.

  [.] the concept "correctly aligned" is transitive: [type A to B, B to C, then also A to C, implicitly].

Hooray!
(0006255)
eblake (manager)
2023-04-06 15:42
edited on: 2023-04-13 15:50

Proposed Interpretation response (superseded by Note: 0006262)
------------------------
The standard clearly states that when a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure maps onto the sa_family field of the sockaddr structure and when a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field maps onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family, and conforming implementations must conform to this.

Rationale:
-------------
In stating these field mapping requirements when a cast operator is applied to the various socket address structures, the standard defines the behavior in circumstances where the behavior is undefined in the ISO C standard. The onus is on implementations to ensure that these mappings are as described in the standard, making use of implementation-specific extensions if necessary, even though this is not stated explicitly.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------

On page 386 line 13115 section <sys/socket.h> DESCRIPTION, change:

    
When a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family.


to:

    
When a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, or vice versa, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, or vice versa, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family. When a pointer to a sockaddr structure is cast as a pointer to a protocol-specific address structure, or vice versa, the sa_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family. Additionally, the structures shall be defined in such a way that these casts do not cause the compiler to produce diagnostics about aliasing issues in accessing the sa_family_t member of these structures when compiling conforming application (xref to XBD section 2.2) source files.



On page 390 line 13260 section <sys/socket.h> APPLICATION USAGE, append a sentence:

    
Note that this example only deals with size and alignment; see RATIONALE for additional issues related to these structures.



On page 390 line 13291 section <sys/socket.h>, change RATIONALE from "None" to:

    
Note that defining the sockaddr_storage and sockaddr structures using only mechanisms defined in early editions of the ISO C standard may produce aliasing diagnostics when applications use casting between pointers to the various socket address structures. Because of the large body of existing code utilizing sockets in a way that could trigger undefined behavior due to strict aliasing rules, this standard mandates that these structures can alias each other for accessing the sa_family_t member of the structures, so as to preserve well-defined semantics. An implementation's header files may need to use anonymous unions, or even an implementation-specific extension, to comply with the requirements of this standard.


(0006257)
eblake (manager)
2023-04-06 19:24

[Copying a message from Zack Weinberg on https://sourceware.org/pipermail/libc-alpha/2023-April/147046.html] [^]

If I could suggest an additional change, the focus on aliasing
_diagnostics_ rather misses the point IMHO. We don't just want the
compiler to _not complain_ about accesses to sa_family_t, we want it to
treat the accesses as _legitimate_. So, instead of

# Additionally, the structures shall be defined in such a way that
# these casts do not cause the compiler to produce diagnostics about
# aliasing issues in accessing the sa_family_t member of these
# structures when compiling conforming application (xref to XBD section
# 2.2) source files.

may I suggest wording along the lines of

# Additionally, the structures shall be defined in such a way that
# the compiler treats an access to the stored value of the sa_family_t
# member of any of these structures, via an lvalue expression whose type
# involves any other one of these structures, as permissible, despite the
# more restrictive rules listed in ISO C section 6.5p7.
(0006258)
steffen (reporter)
2023-04-06 20:50

RFC 2553 defines

struct sockaddr_storage {
    sa_family_t __ss_family; /* address family */
    /* Following fields are implementation specific */
    char __ss_pad1[_SS_PAD1SIZE];
              /* 6 byte pad, this is to make implementation
              /* specific pad up to alignment field that */
              /* follows explicit in the data structure */
    int64_t __ss_align; /* field to force desired structure */
               /* storage alignment */
    char __ss_pad2[_SS_PAD2SIZE];
              /* 112 byte pad to achieve desired size, */
              /* _SS_MAXSIZE value minus size of ss_family */
              /* __ss_pad1, __ss_align fields is 112 */
};

So sockaddr has a 64-bit alignment. This is as good as it gets but for long double and the newish 128-bit integer types (needed to count false political and "economic" decisions i presume; and whatever).

Linux uses

/*
 * Desired design of maximum size and alignment (see RFC2553)
 */
#define _K_SS_MAXSIZE 128 /* Implementation specific max size */

typedef unsigned short __kernel_sa_family_t;

/*
 * The definition uses anonymous union and struct in order to control the
 * default alignment.
 */
struct __kernel_sockaddr_storage {
        union {
                struct {
                        __kernel_sa_family_t ss_family; /* address family */
                        /* Following field(s) are implementation specific */
                        char __data[_K_SS_MAXSIZE - sizeof(unsigned short)];
                                /* space to achieve desired size, */
                                /* _SS_MAXSIZE value minus size of ss_family */
                };
                void *__align; /* implementation specific desired alignment */
        };
};

which could end up with 32-bit on 32-bit hosts i am afraid.
Looks like a step back compared to RFC 2553 where the 64-bit field emanates all over the place, no? And gives correct alignment but for long double or 128-bit extension no matter what sockaddr actually can be.
Why make it more complicated as it is, especially with a POSIX that bases upon ISO C99? Isn't that a bug in Linux instead, as above??
Surely my understanding is from the last century, anyhow.
(0006259)
steffen (reporter)
2023-04-06 20:55

But what i mean is: there is a multi-decade old standard of the Network Working Group, The Internet Society (several, actually), to which implementers of socket facilities have to comply.
Just point to the according RFCs and state "that has to work" (tm), regardless of what smart people in the C standard and compiler communities choose to do.
(Imho.)
(0006260)
steffen (reporter)
2023-04-06 21:08

Mind you. 64-bit alignment is as good as it gets but for long double and the newish 128-bit integer, right? As is standardized for sockaddr_storage.
I think sometimes a step back is the proper thing to do.
(0006261)
ajosey (manager)
2023-04-07 04:53

Interpretation proposed: 7 April 2023
(0006262)
eblake (manager)
2023-04-13 15:45
edited on: 2023-05-25 16:31

Proposed Interpretation response (superseded by Note: 0006290)
------------------------
The standard clearly states that when a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure maps onto the sa_family field of the sockaddr structure and when a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field maps onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family, and conforming implementations must conform to this.

Rationale:
-------------
In stating these field mapping requirements when a cast operator is applied to the various socket address structures, the standard defines the behavior in circumstances where the behavior is undefined in the ISO C standard. The onus is on implementations to ensure that these mappings are as described in the standard, making use of implementation-specific extensions if necessary, even though this is not stated explicitly.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------

On page 386 line 13115 section <sys/socket.h> DESCRIPTION, change:

    
When a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family.


to:

    
When a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, or vice versa, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, or vice versa, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family. When a pointer to a sockaddr structure is cast as a pointer to a protocol-specific address structure, or vice versa, the sa_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family. Additionally, the structures shall be defined in such a way that the compiler treats an access to the stored value of the sa_family_t member of any of these structures, via an lvalue expression whose type involves any other one of these structures, as permissible, despite the more restrictive expression rules on stored value access as stated in the ISO C standard.


On page 390 line 13260 section <sys/socket.h> APPLICATION USAGE, append a sentence:

    
Note that this example only deals with size and alignment; see RATIONALE for additional issues related to these structures.



On page 390 line 13291 section <sys/socket.h>, change RATIONALE from "None" to:

    
Note that defining the sockaddr_storage and sockaddr structures using only mechanisms defined in early editions of the ISO C standard may produce aliasing diagnostics when applications use casting between pointers to the various socket address structures. Because of the large body of existing code utilizing sockets in a way that could trigger undefined behavior due to strict aliasing rules, this standard mandates that these structures can alias each other for accessing the sa_family_t member of the structures, so as to preserve well-defined semantics. An implementation's header files may need to use anonymous unions, or even an implementation-specific extension, to comply with the requirements of this standard.


(0006263)
agadmin (administrator)
2023-04-14 15:20

Interpretation re-proposed: 14 April 2023 (now based on bugnote 6262)
(0006268)
eblake (manager)
2023-04-21 15:24

Comment from Alejandro Colomar at https://sourceware.org/pipermail/libc-alpha/2023-April/147547.html: [^]

The wording I see in <https://austingroupbugs.net/view.php?id=1641#c6262> [^]
doesn't seem to cover the case of aliasing a sockaddr_storage as a
protocol-specific address for setting other members.

Aliasing rules don't allow one to declare an object of type
sockaddr_storage and then fill the structure as if it were another
structure, even if alignment and size are correct. We would need
some wording that says something like:

When a pointer to a sockaddr_storage structure is first aliased as a
pointer to a protocol-specific address structure, the effective type
of the object will be set to the protocol-specific structure.

This is similar to what happens when malloc(3) is assigned to a
non-character type. That's a big hammer, but it does the job. Maybe
we would need some looser language? I CCd GCC, in case they have
concerns about this wording.
(0006289)
geoffclare (manager)
2023-05-25 16:23
edited on: 2023-05-25 16:24

Re: Note: 0006268 the suggestion of "... the effective type of the object will be set ..." would create a conflict with the C standard. (It says what the effective type of an object is - we can't say that it's something else.)

(0006290)
eblake (manager)
2023-05-25 16:23

Interpretation response
------------------------
The standard clearly states that when a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure maps onto the sa_family field of the sockaddr structure and when a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field maps onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family, and conforming implementations must conform to this.

Rationale:
-------------
In stating these field mapping requirements when a cast operator is applied to the various socket address structures, the standard defines the behavior in circumstances where the behavior is undefined in the ISO C standard. The onus is on implementations to ensure that these mappings are as described in the standard, making use of implementation-specific extensions if necessary, even though this is not stated explicitly.

Notes to the Editor (not part of this interpretation):
-------------------------------------------------------
On page 386 line 13115 section <sys/socket.h> DESCRIPTION, change:

    
When a pointer to a sockaddr_storage structure is cast as a pointer to a sockaddr structure, the ss_family field of the sockaddr_storage structure shall map onto the sa_family field of the sockaddr structure. When a pointer to a sockaddr_storage structure is cast as a pointer to a protocol-specific address structure, the ss_family field shall map onto a field of that structure that is of type sa_family_t and that identifies the protocol’s address family.


to:

    
When a pointer to a sockaddr_storage structure is converted to a pointer to a sockaddr structure, or vice versa, the ss_family member of the sockaddr_storage structure shall map onto the sa_family member of the sockaddr structure. When a pointer to a sockaddr_storage structure is converted to a pointer to a protocol-specific address structure, or vice versa, the ss_family member shall map onto a member of that structure that is of type sa_family_t that identifies the protocol’s address family. When a pointer to a sockaddr structure is converted to a pointer to a protocol-specific address structure, or vice versa, the sa_family member shall map onto a member of that structure that is of type sa_family_t that identifies the protocol’s address family. Additionally, the structures shall be defined in such a way that the compiler treats an access to the stored value of the sa_family_t member of any of these structures, via an lvalue expression whose type involves any other one of these structures, as permissible, despite the more restrictive expression rules on stored value access as stated in the ISO C standard. Similarly, when a pointer to a sockaddr_storage or sockaddr structure is converted to a pointer to a protocol-specific address structure, the compiler shall treat an access (using this converted pointer) to the stored value of any member of the protocol-specific structure as permissible. The application shall ensure that the protocol-specific address structure corresponds to the family indicated by the member with type sa_family_t of that structure and the pointed-to object has sufficient memory for addressing all members of the protocol-specific structure.


On page 390 line 13260 section <sys/socket.h> APPLICATION USAGE, append a sentence:

    
Note that this example only deals with size and alignment; see RATIONALE for additional issues related to these structures.


On page 390 line 13291 section <sys/socket.h>, change RATIONALE from "None" to:

    
Note that defining the sockaddr_storage and sockaddr structures using only mechanisms defined in early editions of the ISO C standard may produce aliasing diagnostics when applications use casting between pointers to the various socket address structures. Because of the large body of existing code utilizing sockets in a way that could trigger undefined behavior due to strict aliasing rules, this standard mandates that these structures can alias each other for accessing the sa_family_t member of the structures (or other members for protocol-specific structure references), so as to preserve well-defined semantics. An implementation's header files may need to use anonymous unions, or even an implementation-specific extension, to comply with the requirements of this standard.
(0006291)
agadmin (administrator)
2023-05-25 17:17

Interpretation re-proposed: 25 May 2023 (now based on bugnote 6290
(0006368)
agadmin (administrator)
2023-06-29 09:27

Interpretation approved: 29 June 2023
(0006396)
mirabilos (reporter)
2023-07-21 14:04

The problem with POSIX “defin[ing] the behavior in circumstances where the behavior is undefined in the ISO C standard” is that compilers like GCC do not have an option -std=posix, they only act according to the C standard, and the OS cannot give extra guarantees.

Additionally, when the C standard explicitly says it’s UB, not IB, anything can happen, so I don’t think if ISO C says UB then any other standard can relax that sufficiently.
(0006397)
mirabilos (reporter)
2023-07-22 02:36

Is there a concrete suggestion as how to actually implement this with, say, GCC __attribute__((…)) extensions?

The thread linked from https://www.austingroupbugs.net/view.php?id=1641 [^] contains a response by dalias saying that using transparent unions would not work, because e.g. changing the second bind(2) parameter’s type to the transparent union type, while will work in direct call context, will change the function pointer obtained from the bind function, and cause havoc when trying to store this. And it’s not clear that without that UB is fully avoided in normal use.
(0006398)
bastien (reporter)
2023-07-22 08:08

may_alias attribute on typedef is a big hammer and I think will work

- Issue History
Date Modified Username Field Change
2023-03-18 07:52 bastien New Issue
2023-03-18 07:52 bastien Name => Bastien Roucaries
2023-03-18 07:52 bastien Organization => debian
2023-03-18 07:52 bastien Section => sys/socket.h
2023-03-18 07:52 bastien Page Number => Application usage
2023-03-18 07:52 bastien Line Number => sockaddr_storage
2023-03-18 07:53 bastien Note Added: 0006207
2023-03-18 07:53 bastien Issue Monitored: bastien
2023-03-20 13:20 wlerch Note Added: 0006208
2023-03-20 13:38 bastien Note Added: 0006209
2023-03-20 23:06 steffen Note Added: 0006211
2023-03-21 12:01 hvd Note Added: 0006212
2023-03-21 23:09 sam_james Note Added: 0006215
2023-03-21 23:33 steffen Note Added: 0006216
2023-03-22 09:42 bastien Note Added: 0006217
2023-03-22 21:56 steffen Note Added: 0006227
2023-03-30 15:20 eblake Note Added: 0006238
2023-03-30 15:22 eblake Interp Status => ---
2023-03-30 15:22 eblake Final Accepted Text => see Note: 0006238
2023-03-30 15:22 eblake Status New => Resolved
2023-03-30 15:22 eblake Resolution Open => Accepted As Marked
2023-03-30 15:22 eblake Tag Attached: issue8
2023-04-03 16:31 eblake Status Resolved => Under Review
2023-04-03 16:31 eblake Resolution Accepted As Marked => Reopened
2023-04-03 16:36 eblake Note Added: 0006249
2023-04-03 22:42 steffen Note Added: 0006253
2023-04-03 22:44 steffen Note Added: 0006254
2023-04-06 15:42 eblake Note Added: 0006255
2023-04-06 15:43 eblake Interp Status --- => Pending
2023-04-06 15:43 eblake Final Accepted Text see Note: 0006238 => see Note: 0006255
2023-04-06 15:43 eblake Status Under Review => Interpretation Required
2023-04-06 15:43 eblake Resolution Reopened => Accepted As Marked
2023-04-06 15:44 eblake Tag Attached: tc3-2008
2023-04-06 15:44 eblake Tag Detached: issue8
2023-04-06 19:24 eblake Note Added: 0006257
2023-04-06 20:50 steffen Note Added: 0006258
2023-04-06 20:55 steffen Note Added: 0006259
2023-04-06 21:08 steffen Note Added: 0006260
2023-04-07 04:53 ajosey Interp Status Pending => Proposed
2023-04-07 04:53 ajosey Note Added: 0006261
2023-04-13 15:45 eblake Note Added: 0006262
2023-04-13 15:46 eblake Final Accepted Text see Note: 0006255 => see Note: 0006262
2023-04-13 15:48 eblake Note Edited: 0006255
2023-04-13 15:50 eblake Note Edited: 0006255
2023-04-14 15:20 agadmin Note Added: 0006263
2023-04-21 15:24 eblake Note Added: 0006268
2023-05-25 16:23 geoffclare Note Added: 0006289
2023-05-25 16:23 eblake Note Added: 0006290
2023-05-25 16:24 geoffclare Note Edited: 0006289
2023-05-25 16:25 eblake Interp Status Proposed => Pending
2023-05-25 16:25 eblake Final Accepted Text see Note: 0006262 => see Note: 0006290
2023-05-25 16:31 geoffclare Note Edited: 0006262
2023-05-25 16:31 geoffclare Note Edited: 0006262
2023-05-25 17:17 agadmin Note Added: 0006291
2023-05-25 20:15 agadmin Interp Status Pending => Proposed
2023-06-29 09:27 agadmin Interp Status Proposed => Approved
2023-06-29 09:27 agadmin Note Added: 0006368
2023-07-21 14:04 mirabilos Note Added: 0006396
2023-07-22 02:36 mirabilos Note Added: 0006397
2023-07-22 08:08 bastien Note Added: 0006398
2023-08-17 10:51 geoffclare Status Interpretation Required => Applied
2023-08-17 10:51 geoffclare Tag Attached: applied_after_i8d3
2024-06-11 09:07 agadmin Status Applied => Closed


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker