From owner-freebsd-bugs@FreeBSD.ORG Sat Dec 29 13:10:02 2007 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0029716A41A for ; Sat, 29 Dec 2007 13:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id D664813C467 for ; Sat, 29 Dec 2007 13:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.14.2/8.14.2) with ESMTP id lBTDA1vN030146 for ; Sat, 29 Dec 2007 13:10:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.2/8.14.1/Submit) id lBTDA1rM030145; Sat, 29 Dec 2007 13:10:01 GMT (envelope-from gnats) Resent-Date: Sat, 29 Dec 2007 13:10:01 GMT Resent-Message-Id: <200712291310.lBTDA1rM030145@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Antoine Brodin Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6BE5816A420 for ; Sat, 29 Dec 2007 13:09:19 +0000 (UTC) (envelope-from antoine@peanut.dreadbsd.org) Received: from peanut.dreadbsd.org (peanut.dreadbsd.org [82.67.196.50]) by mx1.freebsd.org (Postfix) with ESMTP id 6EEF113C457 for ; Sat, 29 Dec 2007 13:09:17 +0000 (UTC) (envelope-from antoine@peanut.dreadbsd.org) Received: from peanut.dreadbsd.org (localhost [127.0.0.1]) by peanut.dreadbsd.org (8.14.2/8.14.2) with ESMTP id lBTD9Ftf019605 for ; Sat, 29 Dec 2007 14:09:15 +0100 (CET) (envelope-from antoine@peanut.dreadbsd.org) Received: (from antoine@localhost) by peanut.dreadbsd.org (8.14.2/8.14.2/Submit) id lBTD9EAG019604; Sat, 29 Dec 2007 14:09:14 +0100 (CET) (envelope-from antoine) Message-Id: <200712291309.lBTD9EAG019604@peanut.dreadbsd.org> Date: Sat, 29 Dec 2007 14:09:14 +0100 (CET) From: Antoine Brodin To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Cc: Subject: bin/119129: __stack_chk_guard setup is bogus in src/lib/libc/sys/stack_protector.c X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Antoine Brodin List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 29 Dec 2007 13:10:02 -0000 >Number: 119129 >Category: bin >Synopsis: __stack_chk_guard setup is bogus in src/lib/libc/sys/stack_protector.c >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Dec 29 13:10:01 UTC 2007 >Closed-Date: >Last-Modified: >Originator: Antoine Brodin >Release: FreeBSD 8.0-CURRENT i386 >Organization: none >Environment: System: FreeBSD barton.dreadbsd.org. 8.0-CURRENT FreeBSD 8.0-CURRENT #0: Mon Dec 3 17:11:47 CET 2007 root@barton.dreadbsd.org.:/usr/obj/usr/src/sys/BARTON i386 >Description: When compiling with -fstack-protector-all and executing a binary, __stack_chk_guard is always initialized to 0xff0a0000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000. (at least on i386). >How-To-Repeat: %%% cat > b.c << EOF #include extern long __stack_chk_guard[8]; int main(void) { int i; for (i = 0; i < 8; i++) printf("%lx\n", __stack_chk_guard[i]); return 0; } EOF gcc -fstack-protector-all b.c ./a.out %%% It gives: ./a.out ff0a0000 0 0 0 0 0 0 0 Where is the problem ? The length returned by sysctl(mib, 2, __stack_chk_guard, &len, NULL, 0) is not sizeof(__stack_chk_guard) so the default canary is used: %%% cat > a.c << EOF #include #include #include int main(void) { long stack_chk_guard[8] = {0, 0, 0, 0, 0, 0, 0, 0}; int mib[2]; size_t len; int i, ret; mib[0] = CTL_KERN; mib[1] = KERN_ARND; len = sizeof(stack_chk_guard); ret = sysctl(mib, 2, stack_chk_guard, &len, NULL, 0); if (ret == -1) printf("-1\n"); if (len != sizeof(stack_chk_guard)) printf("%d != %d\n", len, sizeof(stack_chk_guard)); if (ret == -1 || len != sizeof(stack_chk_guard)) { ((unsigned char *)(void *)stack_chk_guard)[0] = 0; ((unsigned char *)(void *)stack_chk_guard)[1] = 0; ((unsigned char *)(void *)stack_chk_guard)[2] = '\n'; ((unsigned char *)(void *)stack_chk_guard)[3] = 255; } for (i = 0; i < 8; i++) printf("%lx\n", stack_chk_guard[i]); return 0; } EOF gcc a.c ./a.out %%% It gives: ./a.out 4 != 32 ff0a0000 0 0 0 0 0 0 0 >Fix: There is a bug in either src/lib/libc/sys/stack_protector.c:__guard_setup(), or in src/sys/kern/kern_mib.c:sysctl_kern_arnd(). sysctl_kern_arnd() generates a random long, while __guard_setup assumes it generates a random buffer. On OpenBSD, src/lib/libc/sys/stack_protector.c is the same but src/sys/kern/kern_sysctl.c initializes a buffer for KERN_ARND ( http://fxr.watson.org/fxr/source//kern/kern_sysctl.c?v=OPENBSD#L394 ) >Release-Note: >Audit-Trail: >Unformatted: