<html>
<head>
<base href="http://llvm.org/bugs/" />
</head>
<body><table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Bug ID</th>
<td><a class="bz_bug_link
bz_status_NEW "
title="NEW --- - libxcb-1.11 miscompiles with Clang -O2 on x86_32/linux"
href="http://llvm.org/bugs/show_bug.cgi?id=21573">21573</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>libxcb-1.11 miscompiles with Clang -O2 on x86_32/linux
</td>
</tr>
<tr>
<th>Product</th>
<td>new-bugs
</td>
</tr>
<tr>
<th>Version</th>
<td>unspecified
</td>
</tr>
<tr>
<th>Hardware</th>
<td>PC
</td>
</tr>
<tr>
<th>OS</th>
<td>Linux
</td>
</tr>
<tr>
<th>Status</th>
<td>NEW
</td>
</tr>
<tr>
<th>Severity</th>
<td>normal
</td>
</tr>
<tr>
<th>Priority</th>
<td>P
</td>
</tr>
<tr>
<th>Component</th>
<td>new bugs
</td>
</tr>
<tr>
<th>Assignee</th>
<td>unassignedbugs@nondot.org
</td>
</tr>
<tr>
<th>Reporter</th>
<td>joakim.gebart@eistec.se
</td>
</tr>
<tr>
<th>CC</th>
<td>llvmbugs@cs.uiuc.edu
</td>
</tr>
<tr>
<th>Classification</th>
<td>Unclassified
</td>
</tr></table>
<p>
<div>
<pre>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;
}</pre>
</div>
</p>
<hr>
<span>You are receiving this mail because:</span>
<ul>
<li>You are on the CC list for the bug.</li>
</ul>
</body>
</html>