Search code examples
c++caddress-sanitizer

Subtracting pointers with structure data


I found some legacy code and think it has UB in subtracting pointers. If i right and UB is here - can i find it with ASAN? I try option -fsanitize=address,pointer-subtract, but it doesn't find problem.

g++ -O0 -fsanitize=address,pointer-subtract main.c
ASAN_OPTIONS=detect_invalid_pointer_pairs=1 ./a.out

Or maybe i mistake and there is no UB?

#define ATTRIBUTE_PACKED_1 __attribute__((aligned(1),packed))
typedef struct DAT
{
    unsigned int IP;
    unsigned short port;
} ATTRIBUTE_PACKED_1 Data;

int main(void)
{
    static Data data;
    int diff = ((unsigned char*) &data) - ((unsigned char*) &data.port);

return 0;
}

Solution

  • Casting pointers to unsigned char* for the purpose of accessing raw bytes, and casting pointers for the purpose of performing pointer arithmetic within an object, or an array of objects (in this case, data can be treated as an array of 1 Data object), are well-defined behaviors in the C and C++ standards.

    However, the address of port is located after the address of data in memory, so your subtraction will result in a negative offset, which may or may not be what you are looking for. To get the byte offset of port within data, you would need to subtract the addresses in the opposite order:

    int offset = ((unsigned char*) &data.port) - ((unsigned char*) &data);