Search code examples
c++macospointersalignment

How to fix unaligned pointer (char**)


Clang 3.3 UBSan (undefined behavior sanitizer) flagged the following code for unaligned access:

Address.cc:545:27: runtime error: load of misaligned address 0x60c00000a7df for type 'char *', which requires 8 byte alignment
0x60c00000a7df: note: pointer points here
 00 00 00 00 ef  a7 00 00 c0 60 00 00 00  00 00 00 00 00 00 00 c0  a8 64 0c 00 00 00 00 00  00 00 00
             ^
Address.cc:547:19: runtime error: reference binding to misaligned address 0x60c00000a7ef for type 'const struct in_addr', which requires 4 byte alignment
0x60c00000a7ef: note: pointer points here
 00 00 00 00 c0  a8 64 0c 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00
             ^

The code in question is shown below (ignore the incorrect return type for operator=):

bool
Ip::Address::operator =(const struct hostent &s)
{
    struct in_addr* ipv4 = NULL;

    switch (s.h_addrtype) {

    case AF_INET:
        // Line 545 below
        ipv4 = (in_addr*)(s.h_addr_list[0]);
        // Line 547 below
        operator=(*ipv4);
        break;
    ...
}

And the hostent structure:

struct hostent {
  char    *h_name;        /* official name of host */
  char    **h_aliases;    /* alias list */
  int     h_addrtype;     /* host address type */
  int     h_length;       /* length of address */
  char    **h_addr_list;  /* list of addresses */
}

This squawk is produced on a Mac OS X system, and I recall a recent discussion about this being a bug on Xcode or CFE Dev mailing list (but I can't locate it at the moment).

EDIT: Sean McBride was kind enough to provide a link to the email: -fcatch-undefined-behavior false positive with readdir()? I don't agree with the statement that it can be ignored (because its coming from the OS and not the application), especially since it can cause SIGBUS errors.

How does one re-align the pointers to clear the Clang issues (h_addr is giving me the most trouble)? Can it even be done due to Apple's internal structures depending upon it?


Solution

  • IF you've got a pointer to data which holds the correct values, but at an incorrect offset, you might need to memcpy that data. In your case, turn ipv4 into a stack variable (which will be aligned), and memcpy the s.h_addr_list[0] to ipv4.