Bug#259887: gcc-3.3: Miscompiles automatic dynamic arrays
Package: gcc-3.3
Version: 1:3.3.4-3
Severity: critical
With the option -mpreferred-stack-boundary=2, gcc 3.3.4 is miscompiling
automatic dynamic arrays. Unfortunately both are used in the
crypto/IPsec subsystems of the Linux kernel.
Here is a sample program:
#include <string.h>
int bar(char *s);
int foo(char *s, int len, int x)
{
char buf[x ? len : 0];
if (x) {
memcpy(buf, s, len);
s = buf;
}
return bar(s);
}
With gcc 3.3.4, this produces:
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.file "b.c"
.text
.p2align 4,,15
.globl foo
.type foo, @function
foo:
pushl %ebp
xorl %eax, %eax
movl %esp, %ebp
subl $24, %esp
movl 16(%ebp), %ecx
movl %edi, -4(%ebp)
movl 12(%ebp), %edx
movl %esp, %edi
movl %ebx, -12(%ebp)
movl %esi, -8(%ebp)
decl %edx
movl 8(%ebp), %esi
testl %ecx, %ecx
setne %al
decl %eax
orl %eax, %edx
addl $19, %edx
andl $-4, %edx
---------------------------------------------------------------------
subl %edx, %esp
leal 27(%esp), %ebx
andl $-16, %ebx
Note the offset 27. The same program when compiled with gcc 3.2.3
produces similar output but it uses an offset of 15.
Suppose that len = 16, x != 0, and %esp & 15 = 8 before the subl.
That means %edx = (15 + 19) & ~3 = 32. So %esp & 15 is still 8
after the subtraction. That is, %esp = 16x + 8. Hence
%ebx = (%esp + 27) & ~15 = (16x + 35) & ~15 = 16x + 32 = %esp + 24.
Therefore buf will only contain 8 bytes of space instead of 16
bytes.
---------------------------------------------------------------------
testl %ecx, %ecx
jne .L5
.L4:
movl %esi, (%esp)
call bar
movl %edi, %esp
movl -12(%ebp), %ebx
movl -8(%ebp), %esi
movl -4(%ebp), %edi
movl %ebp, %esp
popl %ebp
ret
.p2align 4,,7
.L5:
movl 12(%ebp), %eax
movl %esi, 4(%esp)
movl %ebx, %esi
movl %eax, 8(%esp)
movl %ebx, (%esp)
call memcpy
jmp .L4
.size foo, .-foo
.section .note.GNU-stack,"",@progbits
.ident "GCC: (GNU) 3.3.4 (Debian 1:3.3.4-3)"
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Since this bug can lead to remotely triggered crashes and possibly
exploits I'm rating it as critical.
-- System Information
Debian Release: testing/unstable
Kernel Version: Linux gondolin 2.4.26-1-686-smp #1 SMP Sat May 1 19:17:11 EST 2004 i686 GNU/Linux
Versions of the packages gcc-3.3 depends on:
ii binutils 2.14.90.0.7-8 The GNU assembler, linker and binary utiliti
ii cpp-3.3 3.3.4-1 The GNU C preprocessor
ii gcc-3.3-base 3.3.4-1 The GNU Compiler Collection (base package)
ii libc6 2.3.2.ds1-13 GNU C Library: Shared libraries and Timezone
ii libgcc1 3.3.4-1 GCC support library
Reply to: