From christianbiere@gmx.de  Mon Feb 27 21:14:11 2006
Return-Path: <christianbiere@gmx.de>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id B601D16A420
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 27 Feb 2006 21:14:11 +0000 (GMT)
	(envelope-from christianbiere@gmx.de)
Received: from mail.gmx.net (mail.gmx.de [213.165.64.20])
	by mx1.FreeBSD.org (Postfix) with SMTP id B7B3A43D49
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 27 Feb 2006 21:14:10 +0000 (GMT)
	(envelope-from christianbiere@gmx.de)
Received: (qmail invoked by alias); 27 Feb 2006 21:14:08 -0000
Received: from reverse-82-141-49-115.dialin.kamp-dsl.de (EHLO localhost) [82.141.49.115]
  by mail.gmx.net (mp017) with SMTP; 27 Feb 2006 22:14:08 +0100
Message-Id: <20060227211447.GA5140@cyclonus>
Date: Mon, 27 Feb 2006 22:14:47 +0100
From: Christian Biere <christianbiere@gmx.de>
To: FreeBSD-gnats-submit@freebsd.org
Subject: panic: uipc 3
X-Send-Pr-Version: 3.113

>Number:         93914
>Category:       kern
>Synopsis:       [socket] panic: uipc 3
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Feb 27 21:20:02 GMT 2006
>Closed-Date:    Sat Oct 14 11:42:17 GMT 2006
>Last-Modified:  Sat Oct 14 11:42:17 GMT 2006
>Originator:     Christian Biere
>Release:        FreeBSD 6.0-RELEASE-p4 i386
>Organization:
>Environment:
System: FreeBSD vs04 6.0-RELEASE-p4 FreeBSD 6.0-RELEASE-p4 #0: Thu Feb 9 15:02:18 CET 2006 jonsonn@elaine.jbhosting.de:/usr/obj/usr/src/sys/GENERIC i386

>Description:
By sending a datagram with a control message over a unix domain socket
to a unix domain socket of type SOCK_STREAM it is possible to cause
a kernel panic.
>How-To-Repeat:

$ cat > uipc3.c <<EOF && cc -o uipc3 && ./uipc3 /var/run/log
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <errno.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>

#define ARRAY_LEN(x) (sizeof (x) / sizeof (x)[0])

static int
set_socket_address(struct sockaddr_un *sun, const char *path)
{
  static const struct sockaddr_un zero_sun;

  assert(sun);
  assert(path);
  
  *sun = zero_sun;
  if (strlen(path) >= sizeof sun->sun_path) {
    fprintf(stderr, "sockpath is too long\n");
    return -1;
  }
  strncpy(sun->sun_path, path, sizeof sun->sun_path);
  sun->sun_len = SUN_LEN(sun);
  return 0;
}

static int
create_new_socket(int stype)
{
  int fd;

  fd = socket(PF_LOCAL, stype, 0);
  if (-1 == fd) {
    perror("socket(PF_LOCAL, ..., 0)");
    return -1;
  }

  return fd;
}

static int
send_msg(const int fd, const char * const dst_path,
  const struct msghdr * const msg_ptr)
{
  struct msghdr msg;
  struct sockaddr_un sun;

  assert(-1 != fd);
  assert(dst_path);
  assert(msg_ptr);
  
  if (set_socket_address(&sun, dst_path))
    return -1;

  msg = *msg_ptr;
  msg.msg_name = &sun;
  msg.msg_namelen = sizeof sun;
  
  if ((ssize_t) -1 == sendmsg(fd, &msg, 0)) {
    perror("sendmsg()");
    return -1;
  }

  return 0;
}

static int
send_descriptors(const int fd, const char * const dst_path,
  const int * const fd_array, const size_t num_fds)
{
  static const struct cmsghdr zero_cmsg;
  static const struct msghdr zero_msg;
  static struct iovec iov[1];
  struct msghdr msg;
  struct cmsghdr *cmsg;
  size_t data_size;
  ssize_t ret;

  assert(-1 != fd);
  assert(dst_path);
  assert(fd_array);

  data_size = num_fds * sizeof fd_array[0];

  cmsg = malloc(CMSG_SPACE(data_size));
  if (!cmsg) {
    perror("malloc()");
    return -1;
  }

  *cmsg = zero_cmsg;
  cmsg->cmsg_len = CMSG_LEN(data_size);
  cmsg->cmsg_level = SOL_SOCKET;
  cmsg->cmsg_type = SCM_RIGHTS;

  memcpy((char *) cmsg + CMSG_LEN(0), fd_array, data_size);

  msg = zero_msg;
  msg.msg_iov = iov;
  msg.msg_iovlen = ARRAY_LEN(iov);
  msg.msg_control = cmsg;
  msg.msg_controllen = CMSG_LEN(data_size);

  ret = send_msg(fd, dst_path, &msg);
  free(cmsg);
  return ret;
}

void
usage(void)
{
  printf("uipc3 PATH\n");
  exit(EXIT_FAILURE);
}

int
main(int argc, char *argv[])
{
  int s;

  if (argc != 2)
    usage();

  s = create_new_socket(SOCK_STREAM);
  if (-1 == s)
    exit(EXIT_FAILURE);
 
  {
    int fd;

    fd = STDOUT_FILENO;
    send_descriptors(s, argv[1], &fd, 1);
  }

  return 0;
}

/* vi: set ai et ts=2 sts=2 sw=2 cindent: */
EOF

>Fix:
>Release-Note:
>Audit-Trail:

From: Christian Biere <christianbiere@gmx.de>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/93914: panic: uipc 3
Date: Wed, 1 Mar 2006 20:32:11 +0100

 This bug has been fixed in OpenBSD by Miod Vallat. The same
 solution was used to fix the bug in NetBSD. I'd think it
 works for FreeBSD too.
 
 http://article.gmane.org/gmane.os.openbsd.cvs/47416
 http://article.gmane.org/gmane.os.netbsd.bugs/21513
 
 -- 
 Christian

From: Gleb Smirnoff <glebius@FreeBSD.org>
To: Christian Biere <christianbiere@gmx.de>
Cc: FreeBSD-gnats-submit@FreeBSD.org
Subject: Re: kern/93914: panic: uipc 3
Date: Thu, 16 Mar 2006 18:16:16 +0300

   Christian,
 
   I fail to reproduce panic on CURRENT. In unp_connect()
 we've got a check that prevents entering uipc_send() in
 the given case:
 
         if (so->so_type != so2->so_type) {
                 error = EPROTOTYPE;
                 goto bad2;
         }
 
 -- 
 Totus tuus, Glebius.
 GLEBIUS-RIPN GLEB-RIPE

From: Gleb Smirnoff <glebius@freebsd.org>
To: jonas <jonas@schiebtsich.net>
Cc: Christian Biere <christianbiere@gmx.de>, rwatson@freebsd.org,
        bug-followup@freebsd.org
Subject: Re: kern/93914: panic: uipc 3
Date: Thu, 30 Mar 2006 11:35:04 +0400

 On Wed, Mar 29, 2006 at 01:13:53PM +0200, jonas wrote:
 j> Hi Gleb,
 j> 
 j> since Christian doesn't run FreeBSD, I have checked this.
 j> As you can see in the bug report, it was reported to work on 6.0-RELEASE and 
 j> it still does.
 j> For RELENG_6 I can confirm the program quits with 'sendmsg(): Socket operation 
 j> on non-socket'.
 j> For RELENG_6_0 we end up with a 'Fatal trap 12: page fault while in kernel 
 j> mode'.
 j> Sorry, I can't supply a usuable core, but it's easy to reproduce.
 j> Hoping for a fix in RELENG_6_0,
 
 This won't be fixed in RELENG_6_0 since this is not security problem, nor
 data corruption. If I am wrong, then please correct me. This is fixed in
 RELENG_6 and thus will be fixed in all future 6.x releases.
 
 -- 
 Totus tuus, Glebius.
 GLEBIUS-RIPN GLEB-RIPE

From: Jonas Sonntag <jonas@schiebtsich.net>
To: Gleb Smirnoff <glebius@freebsd.org>
Cc: Christian Biere <christianbiere@gmx.de>,
 rwatson@freebsd.org,
 bug-followup@freebsd.org
Subject: Re: kern/93914: panic: uipc 3
Date: Thu, 30 Mar 2006 08:42:14 +0200

 On Thursday 30 March 2006 09:35, Gleb Smirnoff wrote:
 > This won't be fixed in RELENG_6_0 since this is not security problem, nor
 > data corruption. If I am wrong, then please correct me. This is fixed in
 > RELENG_6 and thus will be fixed in all future 6.x releases.
 
 I'd think that 'local user can crash machine' would qualify for an errata 
 patch and in my memory, 6.0 was an errata release, which it is not. So 
 there'll be no fix for RELENG_6_0, of course.
 
 Just checked against RELENG_5_3, here we also quit with 'sendmsg(): Socket 
 operation on non-socket'.
 
 Thanks for your time,
 
 -- 
 br.
 j.

From: Robert Watson <rwatson@FreeBSD.org>
To: Jonas Sonntag <jonas@schiebtsich.net>
Cc: Gleb Smirnoff <glebius@freebsd.org>,
	Christian Biere <christianbiere@gmx.de>, bug-followup@freebsd.org
Subject: Re: kern/93914: panic: uipc 3
Date: Thu, 30 Mar 2006 08:52:21 +0000 (GMT)

 On Thu, 30 Mar 2006, Jonas Sonntag wrote:
 
 > On Thursday 30 March 2006 09:35, Gleb Smirnoff wrote:
 >> This won't be fixed in RELENG_6_0 since this is not security problem, nor
 >> data corruption. If I am wrong, then please correct me. This is fixed in
 >> RELENG_6 and thus will be fixed in all future 6.x releases.
 >
 > I'd think that 'local user can crash machine' would qualify for an errata 
 > patch and in my memory, 6.0 was an errata release, which it is not. So 
 > there'll be no fix for RELENG_6_0, of course.
 >
 > Just checked against RELENG_5_3, here we also quit with 'sendmsg(): Socket 
 > operation on non-socket'.
 
 Well, there is an errata branch for RELENG_6_0, but generally errata branches 
 are used for higher profile/severity issues.  While having users be able to 
 trigger panics locally is bad, bugs of this sort are fixed frequently, and we 
 tend to reserve errata notices for things that are immediately affecting wide 
 audiences, or correct critical problems with key features.
 
 Robert N M Watson
State-Changed-From-To: open->closed 
State-Changed-By: glebius 
State-Changed-When: Sat Oct 14 11:41:51 UTC 2006 
State-Changed-Why:  
According to Audit-Trail the problem is fixed both in HEAD and in RELENG_6. 

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