Re: egcs-1.1.2 ping bug also causes miscompilation of pcbit isdn driver

Lars Heete (hel@admin.de)
Mon, 14 Jun 1999 11:03:48 +0200


On Sun, 13 Jun 1999, you wrote:
>Lars Heete wrote:
>
>> --------------------- test case ----------------------
>> #include <stdio.h>
>> int main(int argc, char **argv) {
>> struct {char c1, c2, c2, 4;} t;
>> t.c4 = 0x78; t.c3 = 0x56; t.c2 = 0x34; t.c1 = 0x12;
>> printf("0x%x\n", *((unsigned long*) &t));
>> return 0;
>> }
>>
>> gives 0x12 with egcs-1.1.2 on i386, instead of 0x78563412.
>
> From the fact that you can write a code like that does not follow that
> you should. Such C should be classified as a bug on its own (and I am
> not talking about trivially missing 'c' before '4' in 't' declaration).
> The first question is how do you know that sizeof(t) is the same as
> sizeof(unsigned long) and that they have the same layout in memory?
> The answer is "you don't" on both counts and if you think that you do
> you are deeply mistaken.

> Even if you guessed right on some particular platform then coding like
> hat you have a pretty good chance that you will cause an unaligned
> access. i386 is much less sensitive than Alpha to that but will take
> a performance hit in any case. On Alpha you will also find nastygrams
> in you Linux log files but this is the way how Linux kernels are coded.
>
> It looks like that egcs-1.1.2 should get extra brownie points for
> exposing shoddy programming practices. :-)

But look for example at this code-fragment from samba-2.0.4b (latest). They are
aware of byteordering and alingment issues. Compile samba with egcs-1.1.2 and
expect wired problems with netbios names on x86, which are hard to reproduce.
This code triggers the mentioned bug (the high byte of the calculated offset
will be set to random values). For the linux kernel, fortunately only the
pcbit driver seems to be affected (I checked the whole kernel with smp and all
scsi and network-drivers).

Lars Heete

/* ------------ from samba-2.0.4b/source/include/byteorder.h -------- */

/* we know that the 386 can handle misalignment and has the "right"
byteorder */
#ifdef __i386__
#define CAREFUL_ALIGNMENT 0
#endif

#ifndef CAREFUL_ALIGNMENT
#define CAREFUL_ALIGNMENT 1
#endif

#ifdef CAREFUL_ALIGNMENT
#define SVAL(buf,pos) (*(uint16 *)((char *)(buf) + (pos)))
#else
#define SVAL(buf,pos) (PVAL(buf,pos)|PVAL(buf,(pos)+1)<<8)
#endif

#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
#define RSVAL(buf,pos) SREV(SVAL(buf,pos))

/* ---------- from samba-2.0.4b/source/include/includes.h ------------- */
#define uint16 unsigned short
#define DEBUG(l, x) /* */

/* ---------- from samba-2.0.4b/source/lib/util.c --------------------- */

/****************************************************************************
find a pointer to a netbios name
****************************************************************************/
static char *name_ptr(char *buf,int ofs)
{
unsigned char c = *(unsigned char *)(buf+ofs);

if ((c & 0xC0) == 0xC0)
{
uint16 l;
char p[2];
memcpy(p,buf+ofs,2);
p[0] &= ~0xC0;
l = RSVAL(p,0);
DEBUG(5,("name ptr to pos %d from %d is %s\n",l,ofs,buf+l));
return(buf + l);
}
else
return(buf+ofs);
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/