February 27, 2010
Green Hills C Compiler bug
I had a rather proud moment a few days ago. I had been looking at a curious piece of compiled code that had an integer promotion bug. Yeah, I have some pretty weird hobbies these days. This particular bug was for the Motorola Coldfire processor. The C code, it turns out, looked like this:
unsigned char table[256] = {0xsomevals} // global array, located on process heapThe compiler compiled the code (the function part of the above) into something like this:
unsigned char array_lookup(unsigned char uc){
return table[(unsigned integer) uc];
}
link a6, #0
;; there would be a 'store registers' command here', I don't remember the syntax at the moment
;; stw.l (a0,d0), (-sp) ?
move.l -4(sp),d0
mvs.b d0,d0 ;; offending line
move.l (0,d0+a0),d0
unlink a6, #0
;; there would be a 'restore register' command here, again I don't remember syntax
rts
For the coldfire assembler unaware, the mvs operation is "move with sign extension". The effect is that the function can return memory logically *before* the array. If the unsigned char passed in is 0x80 or greater, the most significant bit of the byte is a '1'. The sign-extended move operation makes the index value negative. What is interesting here is that the compiler ignored the explicit unsigned integer cast when it dereferenced the element in the array.
It turns out that this was a bug in an older version of the Green Hills compiler. Newer versions don't exhibit this erroneous behavior. I have no information on what versions of the Green Hills compiler are affected by the bug, but if you are a vendor programming Coldfire V4 cpus (mvs was introduced in the Coldfire V4 instruction set), you may want to compile my above code snippet and make sure that your compiler is not affected.
I have to say that I was kind of impressed with myself for finding the bug. The people that produced the compiled code were kind of dumbfounded as to how I stumbled upon it. Since I have started exploring embedded systems security, I've decided that the C language is probably one of the most wretched things in the universe, and that embedded system vendors ought to use as much as peer-reviewed code (read: open source) as possible in their systems. Here I mean both compilers and process code. C compilers for these systems generally don't receive as much scrutiny as desktop application compilers, probably because the target processors are not x86.







by reid
on March 06, 2011
by reid
on November 23, 2009