This is the mail archive of the
glibc-bugs@sourceware.org
mailing list for the glibc project.
[Bug libc/18023] New: extend_alloca is broken (questionable pointer comparison, horrible machine code)
- From: "fweimer at redhat dot com" <sourceware-bugzilla at sourceware dot org>
- To: glibc-bugs at sourceware dot org
- Date: Wed, 25 Feb 2015 09:19:53 +0000
- Subject: [Bug libc/18023] New: extend_alloca is broken (questionable pointer comparison, horrible machine code)
- Auto-submitted: auto-generated
https://sourceware.org/bugzilla/show_bug.cgi?id=18023
Bug ID: 18023
Summary: extend_alloca is broken (questionable pointer
comparison, horrible machine code)
Product: glibc
Version: unspecified
Status: NEW
Severity: normal
Priority: P2
Component: libc
Assignee: fweimer at redhat dot com
Reporter: fweimer at redhat dot com
CC: drepper.fsp at gmail dot com
Flags: security-
Take this example code:
#include <stddef.h>
# define stackinfo_alloca_round(l) (((l) + 15) & -16)
# define extend_alloca(buf, len, newlen) \
(__typeof (buf)) ({ size_t __newlen = stackinfo_alloca_round (newlen); \
char *__newbuf = __builtin_alloca (__newlen); \
if (__newbuf + __newlen == (char *) (buf)) \
len += __newlen; \
else \
len = __newlen; \
__newbuf; })
int f(void *);
int g(void)
{
unsigned long len = 1024;
char *p = __builtin_alloca(len);
while (!f(p)) {
p = extend_alloca(p, len, 2 * len);
}
}
It compiles to this x86_64 machine code with GCC 4.9.2 (-O2):
g:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
pushq %r13
pushq %r12
.cfi_offset 13, -24
.cfi_offset 12, -32
movl $1024, %r12d
pushq %rbx
.cfi_offset 3, -40
movl $16, %ebx
subq $8, %rsp
subq $1040, %rsp
leaq 15(%rsp), %r13
andq $-16, %r13
jmp .L2
.p2align 4,,10
.p2align 3
.L4:
leaq 15(%r12,%r12), %rcx
xorl %edx, %edx
andq $-16, %rcx
leaq 30(%rcx), %rax
addq %rcx, %r12
divq %rbx
salq $4, %rax
subq %rax, %rsp
leaq 15(%rsp), %rax
andq $-16, %rax
leaq (%rax,%rcx), %rdx
cmpq %rdx, %r13
movq %rax, %r13
cmovne %rcx, %r12
.L2:
movq %r13, %rdi
call f
testl %eax, %eax
je .L4
leaq -24(%rbp), %rsp
popq %rbx
popq %r12
popq %r13
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
GCC emits a divq instruction for some reason. We are lucky nothing worse
happens because comparison of two pointers derived from different objects is
not very well-defined as far as C is concerned.
extend_alloca is not widely used; I'll see if I can get rid of it.
--
You are receiving this mail because:
You are on the CC list for the bug.