Cast alignment warnings

Julien ÉLIE julien at trigofacile.com
Mon Aug 1 22:10:29 UTC 2011


Hi Russ,

>> We have in timecaf/timehash an unsigned char class that is cast to an
>> unsigned int* for the sake of sscanf().
>>
>>      n = sscanf(path, "timecaf-%02x/%02x/%04x.CF", (unsigned int*)&class,&t1,&t2);
>
> Actually, I think that one *is* a problem; the address of class is not
> guaranteed to be aligned, since it's a char, which means that sscanf may
> do an unaligned store of an integer.  It's also wrong for other reasons:
> integers are probably either four or eight bytes, so sscanf is going to
> write at least four bytes at the address of class, which is going to
> blithely overwrite neighboring variables on the stack.

Ah, I did not know a cast was actually performed (with a rewrite of the 
memory present in the size of the new type).  Anyway, it makes sense. 
It could also have only be a read:  sscanf() would read the size of the 
new type (and maybe segfaulting if it exceeds what the program is 
allowed to access).



> That looks like a real bug.  The code needs to declare a temporary
> unsigned int variable, sscanf into it, and then store the results in
> class.

OK, I understand.  I will have a look tomorrow.

So it appears that -Wcast-align may be useful :-)
Would it be OK to cast the network calls to void * as you suggested, so 
as to keep -Wcast-align in our checks?



> Also, I think this is only going to work on little-endian systems,
> isn't it? Otherwise, it's always going to write 0 into class.

It would therefore require a subtle use of ntohs/htons calls.
Hm, it should normally be ntohi/itohn for integers, shouldn't it?  But 
these functions are not necessarily present...

-- 
Julien ÉLIE

« Un ami fidèle qui parle très bien votre langue et toutes les
   langues vivantes : le latin, le grec, le celte, etc. » (Astérix)



More information about the inn-workers mailing list