[Workaround]The third SunOS4.1.4 tmpfs bug

From: YAMAMORI Takenori (yamamoriat_private)
Date: Tue Feb 10 1998 - 19:35:53 PST

  • Next message: Cristian Gafton: "Re: [linux-security] vixie cron 3.0.1 continued"

    Now, I think there are *three* different tmpfs bugs on SunOS4.1.4.
    
    The first and the second was fixed by the patches.
    But the third still remains unsolved, but now I wrote a workaround
    program for it, and send it.
    
    
    The first bug is "fifo hard link bug" that can be fixed by the patch
    100507-06 (which is for SunOS4.1.3, but apply to SunOS4.1.4 anyway).
    
        (/tmp is mounted as tmpfs)
        $ cd /tmp
        $ mknod aaa p
        $ ln aaa bbb    # should be hard-link
        $ ls -l
      and then kernel panics.
    
    
    
    The second bug is "assertion failed: tp->tn_dir == NULL" that was
    fixed by the patch 103314-01.
    
        $ cd /tmp
        $ mkdir a
        $ cd a
        $ vi b (write something to it, but keep the file open)
        [ switch screen ]
        $ rm -r /tmp/a
        [ switch screen ]
        (save the file using :w in vi)
      and then kernel panics.
    
    
    However ....
    
    The third tmpfs bug still remains.
    (not solved by 100507-06 nor 103314-01)
    It is "tmpfs symlink bug" I previously said.
    
        (/tmp is mounted as tmpfs)
        $ cd /tmp
        $ mkdir aaa
        $ chmod -w aaa
        $ cd aaa
        $ ln -s bbb ccc    # should be symbolic-link (not hard-link)
    panic: kmem_free: block already free
    
    But Now, I just finished to write a tmpfs-bug-fix program.
    I modload this program to the SunOS4.1.4 kernel and I found
    the tmpfs third bug no more happened !
    
    I shall include this bug-fix program.
    
    (Also in http://www.tt.rim.or.jp/~yamamori/sun/tmpfs-symlink-fix.tar.gz
     but the README is written in Japanese, sorry)
    
    ----- cut here -------------------------------------------------------
    /* tmpfs-symlink-fix.c */
    
    /*
     * tmpfs symlink bug:
     *
     *   (/tmp is mounted as tmpfs)
     *  $ cd /tmp
     *  $ mkdir aaa
     *  $ chmod -w aaa
     *  $ cd aaa
     *  $ ln -s bbb ccc    # should be symbolic-link (not hard-link)
     * panic: kmem_free: block already free
     *
     */
    
    
    #define KERNEL
                         /* change here */
    #define sun4c
    #define __sun4c__   /* for the use of gcc's fix-include */
    /* #define sun4m */
    /* #define __sun4m__ */
    
    
    #include <sys/types.h>
    #include <sys/conf.h>
    #include <sys/buf.h>
    #include <sys/param.h>
    #include <sys/errno.h>
    #include <sys/user.h>
    #include <sys/time.h>
    #include <sys/vfs.h>
    #include <sys/vnode.h>
    #include <sys/ucred.h>
    #include <sys/syslog.h>
    #include <sundev/mbvar.h>
    #include <sun/autoconf.h>
    #include <sun/vddrv.h>
    
    extern  struct vnodeops tmp_vnodeops;
    
    static struct vdldrv vd = {
      VDMAGIC_PSEUDO,      /* Drv_magic */
      "tmpfs-symlink-fix"  /* Drv_name  */
      /* unused members */
    };
    
    static int (*real_tmp_symlink)();
    
    int
    wrap_tmp_symlink(
      struct vnode *vn,
      char *l_name,
      int *va,
      char *t_name,
      struct ucred *cred
    ) {
    
      struct vnode *vn1;
      int err;
    
    #ifdef DEBUG
      printf("tmp_symlink: l_name=%s t_name=%s va=%x\n", l_name, t_name, *va);
    #endif
    
      if ((err = VOP_MKDIR(vn, l_name, va, &vn1, cred)) != 0) {
        return err;
      }
      VOP_RMDIR(vn, l_name, cred);
      return real_tmp_symlink(vn, l_name, va, t_name, cred);
    }
    
    
    int
    xxxinit(
      unsigned int function_code,
      struct vddrv *vdp,
      addr_t vdi,
      struct vdstat *vds
    ) {
    
      int x;
    
      switch(function_code) {
        case VDLOAD:
          vdp->vdd_vdtab = (struct vdlinkage*)&vd;
    
          x = splhigh();
          real_tmp_symlink = tmp_vnodeops.vn_symlink;
          tmp_vnodeops.vn_symlink = wrap_tmp_symlink;
          splx(x);
    
          log(LOG_INFO, "tmpfs symlink-fix module loaded\n");
          return 0;
    
        case VDUNLOAD:
          x = splhigh();
          tmp_vnodeops.vn_symlink = real_tmp_symlink;
          splx(x);
    
          log(LOG_INFO, "tmpfs symlink-fix module unloaded\n");
          return 0;
    
        case VDSTAT:
          return 0;
    
        default:
          return EIO;
      }
    }
    ----- cut here -------------------------------------------------------
    
    ----------------------------------------
    YAMAMORI Takenori  yamamoriat_private
    ----------------------------------------
    



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