This is the mail archive of the glibc-bugs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug libc/18023] New: extend_alloca is broken (questionable pointer comparison, horrible machine code)


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.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]