Subject: kern/4280: sending fd's over AF_UNIX sockets causes kernel panic
To: None <>
From: Chris Jones <>
List: netbsd-bugs
Date: 10/16/1997 12:21:26
>Number:         4280
>Category:       kern
>Synopsis:       sending fd's over AF_UNIX sockets causes kernel panic
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Oct 16 11:35:02 1997
>Originator:     Chris Jones
Chris Jones                            
           Mad scientist in training...
"Is this going to be a stand-up programming session, sir, or another bug hunt?"
>Release:        Yesterday.
System: NetBSD 1.2G NetBSD 1.2G (RUPERT) #4: Thu Jul 24 13:05:55 MDT 1997 mac68k


On two NetBSD-1.2G machines, one a mac68k and one i386, I can cause a
kernel panic by attempting to send multiple file descriptors in one
message.  Even if the man page didn't say this was an acceptable thing
to do, it's a problem because a userland program shouldn't be able to
cause a kernel panic, IMHO.  :)

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <string.h>
#include <sys/un.h>
#include <errno.h>

main(int argc,
     char *argv[])
    struct sockaddr_un sockname;
    int i, sock;
    char buf[1024];
    struct msghdr msg;
    struct cmsghdr cmsg;

    sock = socket(AF_UNIX, SOCK_STREAM, 0);
    if(sock == -1) {
	fprintf(stderr, "%s: socket: %s\n", argv[0], strerror(errno));

    sockname.sun_family = AF_UNIX;
    /* Use /var/run/printer, because it doesn't appear to matter what
       process is on the other end of the socket, as long as it's
       AF_UNIX and SOCK_STREAM. */
    strcpy(sockname.sun_path, "/var/run/printer");
    sockname.sun_len = sizeof(sockname) - sizeof(sockname.sun_path) +
    if(connect(sock, (struct sockaddr *)&sockname, sockname.sun_len)
       == -1) {
	fprintf(stderr, "%s: connect: %s\n", argv[0], strerror(errno));

    /* Send fd's 0, 1, and 2. */
    cmsg.cmsg_len = sizeof(cmsg.cmsg_len) +
	sizeof(cmsg.cmsg_level) + sizeof(cmsg.cmsg_type) +
	sizeof(i) * 3;
    cmsg.cmsg_level = SOL_SOCKET;
    cmsg.cmsg_type = SCM_RIGHTS;
    bcopy(&cmsg, buf, sizeof(cmsg));
    for(i = 0; i < 3; i++)
	bcopy(&i, buf + sizeof(cmsg) + sizeof(i) * i, sizeof(i));
    msg.msg_name = NULL;
    msg.msg_namelen = 0;
    msg.msg_iov = NULL;
    msg.msg_iovlen = 0;
    msg.msg_control = buf;
    msg.msg_controllen = cmsg.cmsg_len;
    msg.msg_flags = 0;
    if(sendmsg(sock, &msg, 0) == -1) {
	fprintf(stderr, "%s: sendmsg: %s\n", argv[0],

    printf("Wow; your machine didn't crash!  You're lucky!\n");


The same program, if it's modified to send fd's one at a time, doesn't
crash anything.