[RTEMS Project] #1401: alignment exception in ioctl(SIOCGIFCONF) on SPARC/gcc-4.3.0

RTEMS trac trac at rtems.org
Sat Nov 22 13:34:42 UTC 2014


#1401: alignment exception in ioctl(SIOCGIFCONF) on SPARC/gcc-4.3.0
------------------------+---------------------
 Reporter:  strauman    |       Owner:  norume
     Type:  defect      |      Status:  new
 Priority:  normal      |   Milestone:  4.9.5
Component:  networking  |     Version:  4.9
 Severity:  normal      |  Resolution:
 Keywords:              |
------------------------+---------------------
Changes (by gedare):

 * milestone:  4.10 => 4.9.5


Old description:

> gcc-4.3.0 generates code which violates the SPARC architecture's
> alignment requirements. This is due to fancy pointer manipulations which
> confuse
> gcc's optimizer because they violate the C99 standard which
> says that pointers to a particular object must always be
> properly aligned (C99 draft, 6.3.2.3-7).
>
> The routine
>
> cpukit/libnetworking/net/if.c:ifconf()
>
> scans all interfaces and their addresses
> (at different protocol levels) and copies
> the addresses out into an array of
> 'struct ifreq' objects.
>
> The problem is that the entities describing
> the interface addresses, namely 'struct sockaddr'
> may be larger than their declared size. This
> applies, e.g., to the link level address where
>
> sa_len == 54
>
> If this happens, the resulting sequence
> of 'struct ifreq' objects is no longer
> a real 'array' but a sequence of
> possibly mis-aligned objects of different
> size.
>
> The copy - algorithm uses a pointer
>
> struct ifreq *ifp
>
> to travel through the destination memory
> buffer and may end up having bad alignment.
> Simplified, 'ifp' iterates as follows:
>
> while ( space_available(ifp) ) {
>   /* copy interface name */
>   memcpy( ifp->ifr_name, src->ifname, 16);
>
>   copy_address(ifp, src);
>
>   ifp++;
>   excess = src->sa.sa_len - sizeof(struct sockaddr);
>   if ( excess > 0 ) {
>     ifp = (struct ifreq*)((caddr_t)ifp + excess);
>   }
>   iterate_source(&src);
> }
>
> gcc assumes that 'ifp' always points to
> a valid 'struct ifreq' object and hence
> is always properly aligned. The 'memcpy'
> operation is optimized into a inlined
> sequence of four 32-bit load/store operations.
>
> However, if the algorithm ever passes
> the 'excess > 0 ' test (and excess is
> not a multiple of four) then 'ifp' is
> misaligned and the 'memcpy' crashes.
>
> The attached fix makes sure the destination
> memory is accessed as a byte stream
> w/o specific alignment requirements.
>
> NOTE: the caller, when unpacking the
> sequence of ifreqs is likely to encounter
> the same problem (see separate bug report
> filed for pppd)

New description:

 gcc-4.3.0 generates code which violates the SPARC architecture's alignment
 requirements. This is due to fancy pointer manipulations which confuse
 gcc's optimizer because they violate the C99 standard which
 says that pointers to a particular object must always be
 properly aligned (C99 draft, 6.3.2.3-7).
 The routine
 cpukit/libnetworking/net/if.c:ifconf()
 scans all interfaces and their addresses
 (at different protocol levels) and copies
 the addresses out into an array of
 'struct ifreq' objects.
 The problem is that the entities describing
 the interface addresses, namely 'struct sockaddr'
 may be larger than their declared size. This
 applies, e.g., to the link level address where
 sa_len == 54
 If this happens, the resulting sequence
 of 'struct ifreq' objects is no longer
 a real 'array' but a sequence of
 possibly mis-aligned objects of different
 size.
 The copy - algorithm uses a pointer
 struct ifreq *ifp
 to travel through the destination memory
 buffer and may end up having bad alignment.
 Simplified, 'ifp' iterates as follows:
 while ( space_available(ifp) ) {
   /* copy interface name */
   memcpy( ifp->ifr_name, src->ifname, 16);
   copy_address(ifp, src);
   ifp++;
   excess = src->sa.sa_len - sizeof(struct sockaddr);
   if ( excess > 0 ) {
     ifp = (struct ifreq*)((caddr_t)ifp + excess);
   }
   iterate_source(&src);
 }
 gcc assumes that 'ifp' always points to
 a valid 'struct ifreq' object and hence
 is always properly aligned. The 'memcpy'
 operation is optimized into a inlined
 sequence of four 32-bit load/store operations.
 However, if the algorithm ever passes
 the 'excess > 0 ' test (and excess is
 not a multiple of four) then 'ifp' is
 misaligned and the 'memcpy' crashes.
 The attached fix makes sure the destination
 memory is accessed as a byte stream
 w/o specific alignment requirements.
 NOTE: the caller, when unpacking the
 sequence of ifreqs is likely to encounter
 the same problem (see separate bug report
 filed for pppd)

--

--
Ticket URL: <http://devel.rtems.org/ticket/1401#comment:2>
RTEMS Project <http://www.rtems.org/>
RTEMS Project


More information about the bugs mailing list