On Mon, Jun 02, 2014 at 07:07:50AM -0400, Jiri B wrote:
Hi,
I got wpa_supplicant core dump. Strange is it is not always
reproducible, it core dumps mostly but sometimes it does not.
CTRL_IFACE monitor attached
/tmp/wpa_ctrl_9659-2\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0
0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0
Abort trap (core dumped)
(gdb) where
#0 0x1545475b9fea in kill () at stdin:2
#1 0x1545475f34bc in __stack_smash_handler (func=0x1543451838c0
wpa_supplicant_ctrl_iface_attach, damaged=Variable damaged is not
available.
) at /usr/src/lib/libc/sys/stack_protector.c:61
#2 0x154345056971 in wpa_supplicant_ctrl_iface_attach () from
/usr/local/sbin/wpa_supplicant
#3 0x15434505789d in wpa_supplicant_ctrl_iface_receive () from
/usr/local/sbin/wpa_supplicant
#4 0x15434501297a in eloop_sock_table_dispatch () from
/usr/local/sbin/wpa_supplicant
#5 0x154345013428 in eloop_run () from /usr/local/sbin/wpa_supplicant
#6 0x154345059e11 in wpa_supplicant_run () from
/usr/local/sbin/wpa_supplicant
#7 0x154345066fda in main () from /usr/local/sbin/wpa_supplicant
The stack smash protector found an off-by-one.
It happens when the printf_encode() function writes a NUL to the
byte past the output buffer.
Attached is a test case which crashes whenever txt - end == 4
during the last loop iteration:
[...]
data[i]=0x8, end - txt = 13
data[i]=0x4c, end - txt = 9
data[i]=0xff, end - txt = 8
data[i]=0xff, end - txt = 4
Abort trap (core dumped)
Fix:
Index: Makefile
===
RCS file: /cvs/ports/security/wpa_supplicant/Makefile,v
retrieving revision 1.14
diff -u -p -r1.14 Makefile
--- Makefile18 Mar 2014 05:57:22 - 1.14
+++ Makefile2 Jun 2014 12:11:45 -
@@ -3,6 +3,7 @@
COMMENT= IEEE 802.1X supplicant
DISTNAME= wpa_supplicant-2.1
+REVISION= 0
CATEGORIES=security net
HOMEPAGE= http://hostap.epitest.fi/wpa_supplicant/
Index: patches/patch-src_utils_common_c
===
RCS file: patches/patch-src_utils_common_c
diff -N patches/patch-src_utils_common_c
--- /dev/null 1 Jan 1970 00:00:00 -
+++ patches/patch-src_utils_common_c2 Jun 2014 12:14:04 -
@@ -0,0 +1,12 @@
+$OpenBSD$
+--- src/utils/common.c.origMon Jun 2 14:12:42 2014
src/utils/common.c Mon Jun 2 14:12:52 2014
+@@ -350,7 +350,7 @@ void printf_encode(char *txt, size_t maxlen, const u8
+ size_t i;
+
+ for (i = 0; i len; i++) {
+- if (txt + 4 end)
++ if (txt + 4 = end)
+ break;
+
+ switch (data[i]) {
/* Off-by-one reproduction based on code from wpa_supplicant.
*
* wpa_supplicant/hostapd / common helper functions, etc.
* Copyright (c) 2002-2007, Jouni Malinen j...@w1.fi
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include stddef.h
#include stdio.h
#include string.h
#include sys/socket.h
#include sys/un.h
void printf_encode(char *txt, size_t maxlen, const unsigned char *data, size_t
len)
{
char *end = txt + maxlen;
size_t i;
for (i = 0; i len; i++) {
#ifdef DO_NOT_OVERFLOW
if (txt + 4 = end)
#else
if (txt + 4 end)
#endif
break;
printf(data[i]=0x%x, end - txt = %d\n, data[i], end - txt);
switch (data[i]) {
case '\':
*txt++ = '\\';
*txt++ = '\';
break;
case '\\':
*txt++ = '\\';
*txt++ = '\\';
break;
case '\e':
*txt++ = '\\';
*txt++ = 'e';
break;
case '\n':
*txt++ = '\\';
*txt++ = 'n';
break;
case '\r':
*txt++ = '\\';
*txt++ = 'r';
break;
case '\t':
*txt++ = '\\';
*txt++ = 't';
break;
default:
if (data[i] = 32 data[i] = 127) {
*txt++ = data[i];
} else {
txt += snprintf(txt, end - txt, \\x%02x,
data[i]);
}
break;
}
}
*txt = '\0';
}
void foo(struct sockaddr_un *from, socklen_t fromlen)
{
char encoded[200];
memset(encoded, 0, sizeof(encoded));
printf_encode