From nobody@FreeBSD.org  Tue Aug  3 10:06:01 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id D3ADE106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  3 Aug 2010 10:06:01 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id C20C68FC14
	for <freebsd-gnats-submit@FreeBSD.org>; Tue,  3 Aug 2010 10:06:01 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o73A61If003826
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 3 Aug 2010 10:06:01 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o73A61Jh003825;
	Tue, 3 Aug 2010 10:06:01 GMT
	(envelope-from nobody)
Message-Id: <201008031006.o73A61Jh003825@www.freebsd.org>
Date: Tue, 3 Aug 2010 10:06:01 GMT
From: Stef Walter <stef@memberwebs.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: struct msghdr.msg_controllen left unititialized in freebsd32_recvmsg
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         149227
>Category:       kern
>Synopsis:       struct msghdr.msg_controllen left unititialized in freebsd32_recvmsg
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kib
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Aug 03 10:10:04 UTC 2010
>Closed-Date:    Tue Aug 10 10:17:19 UTC 2010
>Last-Modified:  Tue Aug 10 10:20:02 UTC 2010
>Originator:     Stef Walter
>Release:        FreeBSD 8.1
>Organization:
>Environment:
FreeBSD a2.ams.npubs.net 8.1-RELEASE FreeBSD 8.1-RELEASE #2: Tue Aug  3 09:15:35 UTC 2010     stef@a2.ams.npubs.net:/usr/obj/usr/src/sys/RACK2  amd64
>Description:
In the freebsd32 compat layer msgdhr.msg_controllen is not set to zero
when no control data was returned via recvmsg. It is left at its original
value, and can cause userland crashes or accesses to uninitialized memory.

This occurs when 32-bit userland (such as in a jail) is running on a 64-bit
kernel and calls recvmsg().

>How-To-Repeat:
/* Will crash or produce erroneous output on 32-bit userland running on 64-bit kernel */
/* gcc -o test_cmsghdr test_cmsghdr.c */

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <err.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

#define SOCKET_PATH "/tmp/cmsghdr.sock"
#define TEST_DATA "This is the test data we sent."

int
perform_send (void)
{
	struct sockaddr_un addr;
	ssize_t sent;
	int sock;

	sock = socket (AF_UNIX, SOCK_DGRAM, 0);
	if (sock < 0)
		err (1, "send socket");

	memset (&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	strncpy (addr.sun_path, SOCKET_PATH, sizeof (addr.sun_path));

	if (connect (sock, (struct sockaddr*)&addr, sizeof (addr)) < 0)
		err (1, "send connect");

	sent = send (sock, TEST_DATA, strlen (TEST_DATA), 0);
	if (sent < 0)
		err (1, "send send");

	if (sent < strlen (TEST_DATA))
		errx (1, "short send");

	close (sock);
	return 0;
}

int
main (void)
{
	char buffer[256];
	char control[256];
	struct sockaddr_un addr;
	struct msghdr msg;
	struct cmsghdr *cmsg;
	struct iovec iov;
	int sock;
	ssize_t len;
	socklen_t slen;

	sock = socket (AF_UNIX, SOCK_DGRAM, 0);
	if (sock < 0)
		err (1, "recv socket");

	memset (&addr, 0, sizeof(addr));
	addr.sun_family = AF_UNIX;
	strncpy (addr.sun_path, SOCKET_PATH, sizeof (addr.sun_path));

	unlink (SOCKET_PATH);
	if (bind (sock, (struct sockaddr*)&addr, sizeof (addr)) < 0)
		err (1, "recv bind");

	if (fork () == 0)
		return perform_send ();

	memset (&iov, 0, sizeof (iov));
	iov.iov_base = buffer;
	iov.iov_len = sizeof (buffer) - 1;

	memset (&msg, 0, sizeof (msg));
	msg.msg_iov = &iov;
	msg.msg_iovlen = 1;
	msg.msg_control = control;
	msg.msg_controllen = sizeof (control);

	/* Screw up memory in these buffers */
	memset (control, 0xAB, sizeof (control));
	memset (buffer, 0xBA, sizeof (buffer));

	len = recvmsg (sock, &msg, 0);
	if (len < 0)
		err (1, "recv recvfrom");

	if (len >= sizeof (buffer))
		err (1, "recv too long");

	buffer[len] = 0;
	warnx ("received data:");
	fprintf (stderr, "%s\n", buffer);

	warnx ("flags: %x", msg.msg_flags);
	warnx ("length of control: %d", msg.msg_controllen);

	if (msg.msg_controllen) {
		for (cmsg = CMSG_FIRSTHDR (&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg))
			warnx ("cmsg of len: 0x%08x", cmsg->cmsg_len);
	}

	close (sock);
	return 0;
}
>Fix:
Will attach a patch

Patch attached with submission follows:

--- ./sys/compat/freebsd32/freebsd32_misc.c.orig	2010-08-03 09:08:40.000000000 +0000
+++ ./sys/compat/freebsd32/freebsd32_misc.c	2010-08-03 09:55:29.000000000 +0000
@@ -1063,4 +1063,6 @@ freebsd32_recvmsg(td, uap)
 		if (control != NULL)
 			error = freebsd32_copy_msg_out(&msg, control);
+		else
+			msg.msg_controllen = 0;
 		
 		if (error == 0)


>Release-Note:
>Audit-Trail:

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/149227: commit references a PR
Date: Tue,  3 Aug 2010 11:23:59 +0000 (UTC)

 Author: kib
 Date: Tue Aug  3 11:23:44 2010
 New Revision: 210796
 URL: http://svn.freebsd.org/changeset/base/210796
 
 Log:
   When compat32 recvmsg(2) does not need to copy out control messages, set
   msg_controllen to 0.
   
   PR:	kern/149227
   Submitted by:	Stef Walter <stef memberwebs com>
   MFC after:	1 weeks
 
 Modified:
   head/sys/compat/freebsd32/freebsd32_misc.c
 
 Modified: head/sys/compat/freebsd32/freebsd32_misc.c
 ==============================================================================
 --- head/sys/compat/freebsd32/freebsd32_misc.c	Tue Aug  3 11:21:17 2010	(r210795)
 +++ head/sys/compat/freebsd32/freebsd32_misc.c	Tue Aug  3 11:23:44 2010	(r210796)
 @@ -1059,6 +1059,8 @@ freebsd32_recvmsg(td, uap)
  		
  		if (control != NULL)
  			error = freebsd32_copy_msg_out(&msg, control);
 +		else
 +			msg.msg_controllen = 0;
  		
  		if (error == 0)
  			error = freebsd32_copyoutmsghdr(&msg, uap->msg);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: linimon 
State-Changed-When: Wed Aug 4 02:17:12 UTC 2010 
State-Changed-Why:  
set as MFC reminder. 


Responsible-Changed-From-To: freebsd-bugs->kib 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Wed Aug 4 02:17:12 UTC 2010 
Responsible-Changed-Why:  

http://www.freebsd.org/cgi/query-pr.cgi?pr=149227 
State-Changed-From-To: patched->closed 
State-Changed-By: kib 
State-Changed-When: Tue Aug 10 10:16:59 UTC 2010 
State-Changed-Why:  
Committed to HEAD and RELENG_8. 

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

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/149227: commit references a PR
Date: Tue, 10 Aug 2010 10:15:46 +0000 (UTC)

 Author: kib
 Date: Tue Aug 10 10:15:34 2010
 New Revision: 211138
 URL: http://svn.freebsd.org/changeset/base/211138
 
 Log:
   MFC r210796:
   When compat32 recvmsg(2) does not need to copy out control messages, set
   msg_controllen to 0.
   
   PR:	kern/149227
 
 Modified:
   stable/8/sys/compat/freebsd32/freebsd32_misc.c
 Directory Properties:
   stable/8/sys/   (props changed)
   stable/8/sys/amd64/include/xen/   (props changed)
   stable/8/sys/cam/   (props changed)
   stable/8/sys/cddl/contrib/opensolaris/   (props changed)
   stable/8/sys/contrib/dev/acpica/   (props changed)
   stable/8/sys/contrib/pf/   (props changed)
   stable/8/sys/dev/xen/xenpci/   (props changed)
 
 Modified: stable/8/sys/compat/freebsd32/freebsd32_misc.c
 ==============================================================================
 --- stable/8/sys/compat/freebsd32/freebsd32_misc.c	Tue Aug 10 09:24:19 2010	(r211137)
 +++ stable/8/sys/compat/freebsd32/freebsd32_misc.c	Tue Aug 10 10:15:34 2010	(r211138)
 @@ -1062,6 +1062,8 @@ freebsd32_recvmsg(td, uap)
  		
  		if (control != NULL)
  			error = freebsd32_copy_msg_out(&msg, control);
 +		else
 +			msg.msg_controllen = 0;
  		
  		if (error == 0)
  			error = freebsd32_copyoutmsghdr(&msg, uap->msg);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
