wpa_supplicant core dump

2014-06-02 Thread Jiri B
Hi,

I got wpa_supplicant core dump. Strange is it is not always
reproducible, it core dumps mostly but sometimes it does not.

j.

# wpa_supplicant -c /etc/wpa_supplicant.conf -D openbsd -i iwn0 -d
...
EAP-PEAP: received 53 bytes encrypted data for Phase 2
EAP-PEAP: Decrypted Phase 2 EAP - hexdump(len=14): 01 af 00 0e 06 50 61 73 73 
77 6f 72 64 3a
EAP-PEAP: received Phase 2: code=1 identifier=175 length=14
EAP-PEAP: Phase 2 Request: type=6
EAP-PEAP: Selected Phase 2 EAP vendor 0 method 6
EAP-GTC: Password not configured
EAPOL: EAP parameter needed
iwn0: CTRL-REQ-OTP-0:[Password:] needed for SSID WifiAP
EAP: method process - ignore=FALSE methodState=MAY_CONT decision=FAIL 
eapRespData=0x0
EAP: EAP entering state SEND_RESPONSE
EAP: No eapRespData available
EAP: EAP entering state IDLE
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
(gdb) thread apply all bt

Thread 1 (process 21621):
#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

Information for inst:wpa_supplicant-2.1

Comment:
IEEE 802.1X supplicant

Description:
wpa_supplicant is the implementation of an IEEE 802.1X supplicant for
wired (Ethernet PAE) and wireless (WPA/WPA2) authentication.

Maintainer: Stuart Henderson st...@openbsd.org

WWW: http://hostap.epitest.fi/wpa_supplicant/


kern.version=OpenBSD 5.5-current (GENERIC.MP) #126: Mon May 12 22:40:04 MDT 2014
t...@amd64.openbsd.org:/usr/src/sys/arch/amd64/compile/GENERIC.MP



Re: wpa_supplicant core dump

2014-06-02 Thread Stefan Sperling
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