The following issue has been SUBMITTED. 
====================================================================== 
https://www.austingroupbugs.net/view.php?id=1641 
====================================================================== 
Reported By:                bastien
Assigned To:                
====================================================================== 
Project:                    1003.1(2016/18)/Issue7+TC2
Issue ID:                   1641
Category:                   System Interfaces
Type:                       Clarification Requested
Severity:                   Editorial
Priority:                   normal
Status:                     New
Name:                       Bastien Roucaries 
Organization:               debian 
User Reference:              
Section:                    sys/socket.h 
Page Number:                Application usage 
Line Number:                sockaddr_storage 
Interp Status:              --- 
Final Accepted Text:         
====================================================================== 
Date Submitted:             2023-03-18 07:52 UTC
Last Modified:              2023-03-18 07:52 UTC
====================================================================== 
Summary:                    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;
        };
};

====================================================================== 

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
======================================================================


  • [1003.1(2016... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group
    • [1003.1... Austin Group Bug Tracker via austin-group-l at The Open Group

Reply via email to