From: Greg B. <gb...@po...> - 2000-11-30 07:07:32
|
G'day Bryan Rittmeyer wrote: > > Basically, I think the problem was with code like this: > > --- > #include <stdio.h> > [...] The compiler I have here (cvs snapshot from about 2 months ago) generates perfectly-well aligned assembler for this C code: .data .align 1 ! bleep aligned to sizeof(short) .type bleep.3,@object .size bleep.3,6 bleep.3: .short 1 .short 2 .short 3 .align 2 ! bloop aligned to sizeof(long) .type bloop.4,@object .size bloop.4,8 bloop.4: .byte 1 .zero 3 ! bloop.boom aligned to sizeof(long) .long 2 > Please note: we're not using the latest toolchain here, and therefore, > can't use the latest kernels. I would hate to go chasing after an > already fixed bug, so I will look into testing the other engineer's code > with the latest stuff as soon as possible. I know it's hard to keep up with these things, but in the long run it's worth the effort. > > It sends a SIGSEGV. I'm currently looking into adding a siginfo struct > > with sufficient information to emulate unaligned accesses efficiently. My two cents worth on the unaligned accesses issue. <RANT> Just Say No to unaligned accesses. Unaligned accesses should only happen as the result of bad code or compiler bugs, both of which need to have their cause fixed and *not* their symptoms covered up with bletcherous bandaids like exception handlers which decode instructions to fake unaligned accesses. Decoding instructions is a job for the CPU (and debuggers), and should *not* be part of the normal operation of the system. The fact that the Linux networking stack currently relies on unaligned accesses in rare circumstances is a bletcherous relic of its i386 heritage and should be hunted down, shot, and its head stuffed and mounted to remind people of how to write portable code. As long as the kernel has fancy exception handlers which allow the networking code to get away with this behaviour, it will only encourage the disease to spread. </RANT> Ok, I feel better now ;-) Seriously now, I'm concerned about the DoS aspect of relying on unaligned access fixups in the networking stack. Data-dependant fixups in general are fine if used to handle events generated by local processes, because they're self-limiting. Send the process SIGBUS or whatever and the problem goes away. But fixups triggered by network packets are not self-limiting in this way; it may be possible to bring a machine to its knees either maliciously or accidentally. The device I'm working on does wireless networking and might in the future be sold for law enforcement or military applications. With portable wireless devices you can't in general "protect the devices with a router"; they have to be reasonably robust. It can't just go gaga when strange packets comes along. What I'm saying is, in the long term a network stack which is DoS-vulnerable on SH4 is *not* acceptable. The only long-term solution I see is to remove the fixups from the unaligned access exception handler and fix the brokenness in the networking code Finally some practical experience which might help others. I recently had to debug Ben Reed's airo.c driver for the Aironet 4800 wireless ethernet card. The machine was responding to ARP but crashing on the first ping packet. It turns out that inserting the following line in the receive interrupt handler "fixed" it: @@ -942,6 +959,7 @@ apriv->stats.rx_dropped++; } else { char *buffer; + skb_reserve(skb,2); /* IP headers on 16 byte boundaries */ buffer = skb_put( skb, len ); bap_setup( apriv, fid, 0x36+sizeof(len), BAP0 ); bap_read( apriv, (u16*)buffer, len, BAP0 ); Quite a few of the Linux network device drivers do this. It's an example of a bandaid which works around alignment problems in a _relatively_ unbletcherous manner. Obviously its a short term solution only, but I hope it might help someone. Greg. -- These are my opinions not PPIs. |