Bugtraq mailing list archives

[Workaround]The third SunOS4.1.4 tmpfs bug


From: yamamori () KT RIM OR JP (YAMAMORI Takenori)
Date: Wed, 11 Feb 1998 12:35:53 +0900


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  yamamori () kt rim or jp
----------------------------------------



Current thread: