From antoine@peanut.dreadbsd.org  Sat Dec 29 13:09:19 2007
Return-Path: <antoine@peanut.dreadbsd.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 6BE5816A420
	for <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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 <FreeBSD-gnats-submit@freebsd.org>; 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 <antoine.brodin@laposte.net>
Reply-To: Antoine Brodin <antoine.brodin@laposte.net>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: __stack_chk_guard setup is bogus in src/lib/libc/sys/stack_protector.c
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         119129
>Category:       kern
>Synopsis:       [libc] [patch] __stack_chk_guard setup is bogus in src/lib/libc/sys/stack_protector.c
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    antoine
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Dec 29 13:10:01 UTC 2007
>Closed-Date:    Mon Mar 24 14:51:06 UTC 2008
>Last-Modified:  Mon Mar 24 14:51:06 UTC 2008
>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 <stdio.h>

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 <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>

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:

From: Antoine Brodin <antoine.brodin@laposte.net>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/119129: __stack_chk_guard setup is bogus in
 src/lib/libc/sys/stack_protector.c
Date: Sat, 29 Dec 2007 15:23:44 +0100

 As the problem is more likely in
 src/sys/kern/kern_mib.c:sysctl_kern_arnd(), this PR may be in "kern"
 category.

From: Antoine Brodin <antoine.brodin@laposte.net>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119129: [libc] __stack_chk_guard setup is bogus in
 src/lib/libc/sys/stack_protector.c
Date: Sun, 30 Dec 2007 12:21:47 +0100

 This is a multi-part message in MIME format.
 
 --Multipart=_Sun__30_Dec_2007_12_21_47_+0100_99Kj1udS0jrX1iLD
 Content-Type: text/plain; charset=US-ASCII
 Content-Transfer-Encoding: 7bit
 
 Here is a patch, tested on i386 only.
 I tried to mimic what OpenBSD does.
 
 --Multipart=_Sun__30_Dec_2007_12_21_47_+0100_99Kj1udS0jrX1iLD
 Content-Type: text/x-diff;
  name="kern_mib.c.diff"
 Content-Disposition: attachment;
  filename="kern_mib.c.diff"
 Content-Transfer-Encoding: 7bit
 
 Index: kern_mib.c
 ===================================================================
 RCS file: /home/ncvs/src/sys/kern/kern_mib.c,v
 retrieving revision 1.85
 diff -u -p -r1.85 kern_mib.c
 --- kern_mib.c	4 Dec 2007 12:28:07 -0000	1.85
 +++ kern_mib.c	30 Dec 2007 10:48:44 -0000
 @@ -153,14 +153,18 @@ SYSCTL_INT(_hw, HW_PAGESIZE, pagesize, C
  static int
  sysctl_kern_arnd(SYSCTL_HANDLER_ARGS)
  {
 -	u_long val;
 +	char buf[256];
 +	size_t len;
  
 -	arc4rand(&val, sizeof(val), 0);
 -	return (sysctl_handle_long(oidp, &val, 0, req));
 +	len = req->oldlen;
 +	if (len > sizeof(buf))
 +		len = sizeof(buf);
 +	arc4rand(buf, len, 0);
 +	return (SYSCTL_OUT(req, buf, len));
  }
  
 -SYSCTL_PROC(_kern, KERN_ARND, arandom, CTLFLAG_RD,
 -	0, 0, sysctl_kern_arnd, "L", "arc4rand");
 +SYSCTL_PROC(_kern, KERN_ARND, arandom, CTLTYPE_OPAQUE | CTLFLAG_RD,
 +    NULL, 0, sysctl_kern_arnd, "", "arc4rand");
  
  static int
  sysctl_hw_physmem(SYSCTL_HANDLER_ARGS)
 
 --Multipart=_Sun__30_Dec_2007_12_21_47_+0100_99Kj1udS0jrX1iLD--
Responsible-Changed-From-To: freebsd-bugs->antoine 
Responsible-Changed-By: antoine 
Responsible-Changed-When: Sun Feb 10 19:17:15 UTC 2008 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=119129 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119129: commit references a PR
Date: Sun, 17 Feb 2008 16:44:56 +0000 (UTC)

 antoine     2008-02-17 16:44:48 UTC
 
   FreeBSD src repository
 
   Modified files:
     sys/kern             kern_mib.c 
   Log:
   Make sysctl_kern_arnd return a random buffer instead of a random long,
   as it is expected by userland (stack protector guard setup for example).
   
   PR:             119129
   Approved by:    rwatson (mentor)
   MFC after:      1 month
   
   Revision  Changes    Path
   1.88      +9 -5      src/sys/kern/kern_mib.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: antoine 
State-Changed-When: Sun Feb 17 16:50:25 UTC 2008 
State-Changed-Why:  
Patched in revision 1.88 of src/sys/kern/kern_mib.c 

http://www.freebsd.org/cgi/query-pr.cgi?pr=119129 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/119129: commit references a PR
Date: Mon, 24 Mar 2008 14:28:39 +0000 (UTC)

 antoine     2008-03-24 14:28:33 UTC
 
   FreeBSD src repository
 
   Modified files:        (Branch: RELENG_7)
     sys/kern             kern_mib.c 
   Log:
   MFC to RELENG_7:
     Make sysctl_kern_arnd return a random buffer instead of a random long,
     as it is expected by userland (stack protector guard setup for example).
   
     PR:             119129
     Approved by:    rwatson (mentor)
     MFC after:      1 month
   
   Revision  Changes    Path
   1.84.2.2  +9 -5      src/sys/kern/kern_mib.c
 _______________________________________________
 cvs-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/cvs-all
 To unsubscribe, send any mail to "cvs-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: antoine 
State-Changed-When: Mon Mar 24 14:50:25 UTC 2008 
State-Changed-Why:  
Close: committed in HEAD and RELENG_7. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=119129 
>Unformatted:
