[LLVMbugs] [Bug 21573] New: libxcb-1.11 miscompiles with Clang -O2 on x86_32/linux
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Fri Nov 14 07:47:18 PST 2014
http://llvm.org/bugs/show_bug.cgi?id=21573
Bug ID: 21573
Summary: libxcb-1.11 miscompiles with Clang -O2 on x86_32/linux
Product: new-bugs
Version: unspecified
Hardware: PC
OS: Linux
Status: NEW
Severity: normal
Priority: P
Component: new bugs
Assignee: unassignedbugs at nondot.org
Reporter: joakim.gebart at eistec.se
CC: llvmbugs at cs.uiuc.edu
Classification: Unclassified
The function get_peer_sock_name in src/xcb_auth.c of libxcb-1.11 generates
broken assembly code on x86_32 when compiled with Clang/LLVM-3.5.0 using -O2
optimization level, this does not happen on -O1 or lower level, it also seems
to work correctly on x86_64 even with -O2.
The C code first calls malloc(), then checks the returned pointer for NULL,
finally calls the function getpeername() or getsockname() via a function
pointer, using the malloc'ed pointer as second argument.
When compiled with -O2 the assembly code generated will (incorrectly)
dereference the pointer returned by malloc() and pass the value pointed at as
second argument to the getpeername() function call.
By coincidence, the uninitialized malloced area may contain a valid pointer
which results in a corrupt heap since the getpeername function will write its
result to an incorrect address.
C-code snippet below:
/* Return a dynamically allocated socket address structure according
to the value returned by either getpeername() or getsockname()
(according to POSIX, applications should not assume a particular
length for `sockaddr_un.sun_path') */
static struct sockaddr *get_peer_sock_name(int (*socket_func)(int,
struct sockaddr
*,
socklen_t *),
int fd)
{
socklen_t socknamelen = sizeof(struct sockaddr) + INITIAL_SOCKNAME_SLACK;
socklen_t actual_socknamelen = socknamelen;
struct sockaddr *sockname = malloc(socknamelen);
if (sockname == NULL)
return NULL;
/* Both getpeername() and getsockname() truncates sockname if
there is not enough space and set the required length in
actual_socknamelen */
if (socket_func(fd, sockname, &actual_socknamelen) == -1) // <======= This
is where the incorrect dereference happens. /////////////
goto sock_or_realloc_error;
if (actual_socknamelen > socknamelen)
{
struct sockaddr *new_sockname = NULL;
socknamelen = actual_socknamelen;
if ((new_sockname = realloc(sockname, actual_socknamelen)) == NULL)
goto sock_or_realloc_error;
sockname = new_sockname;
if (socket_func(fd, sockname, &actual_socknamelen) == -1 ||
actual_socknamelen > socknamelen)
goto sock_or_realloc_error;
}
return sockname;
sock_or_realloc_error:
free(sockname);
return NULL;
}
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20141114/e2439fab/attachment.html>
More information about the llvm-bugs
mailing list