From owner-freebsd-bugs@FreeBSD.ORG Tue Aug 3 10:10:09 2010 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 B8F9A1065674 for ; Tue, 3 Aug 2010 10:10:09 +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 815408FC0C for ; Tue, 3 Aug 2010 10:10:05 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id o73AA5Li019666 for ; Tue, 3 Aug 2010 10:10:05 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o73AA5XD019665; Tue, 3 Aug 2010 10:10:05 GMT (envelope-from gnats) Resent-Date: Tue, 3 Aug 2010 10:10:05 GMT Resent-Message-Id: <201008031010.o73AA5XD019665@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, Stef Walter Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D3ADE106566B for ; 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 ; 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 ; 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 To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: kern/149227: struct msghdr.msg_controllen left unititialized in freebsd32_recvmsg X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 03 Aug 2010 10:10:09 -0000 >Number: 149227 >Category: kern >Synopsis: struct msghdr.msg_controllen left unititialized in freebsd32_recvmsg >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Aug 03 10:10:04 UTC 2010 >Closed-Date: >Last-Modified: >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 #include #include #include #include #include #include #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: >Unformatted: