Bugtraq mailing list archives

tmpfs panic fix - was Re: udp packet storms - ping death


From: 8lgm () bagpuss demon co uk ([8LGM] Security Team)
Date: Sat, 5 Nov 1994 21:04:49 +0000 (GMT)


David A. Wagner wrote:

ObBug: if you use the SunOS tmpfs, try

cd /tmp; /usr/etc/mknod fifo p; ln fifo link; ls -ClFg link fifo

...but not at peak hours!

Sun knows about it and after a year, there's still no fix.  [As
far as I know -- if there's one, I'd love to hear of it, so I can
tell the computer center here to add the darn thing: after hearing
of this one, they hacked the kernel and removed the mkfifo and
mknod S_IFIFO system calls. <sigh>]

Here is our workaround for this.  The problem is that for a special file,
tmp_link() tries to update the link count (va_nlink in vattr) in the snode's
vnode, rather than the real vnode.

We take no responsibility for this code; it was developed without any source.
Read it through and then use it if you like it.  It works for us on SunOS 4.1.1
on a Sun3.  Not tested on anything else.

If you do use it, we'd be interested to hear whether or not it works for you.
Please mail 8lgm () bagpuss demon co uk.

To use this, create the following program - 8lgm_tmpfs.c.  Then compile and
load using the commands described in the header comment.

8<------------------------- cut here -------------------------

/*
 * 8lgm_tmpfs.c -  SunOS 4.1.x TMPFS bugfix.
 * Copyright (C) 1994 by [8LGM].
 *
 * This works around a fatal bug in tmpfs, reported to Bugtraq
 * by dawagner () phoenix princeton edu (David A. Wagner) on 2/11/94.
 *
 * Bug:
 *      cd /tmp; /usr/etc/mknod fifo p; ln fifo link; ls -ClFg link fifo
 *      panics the kernel with a bus error.
 *
 * To use:
 *      cc -c -O -DKERNEL -D<kernel-arch> 8lgm_tmpfs.c
 *      modload 8lgm_tmpfs.o
 */

#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;
struct  vdldrv vd;

int     (*real_tmp_link)();
int     loaded_8lgm = 0;

int
tmp_link_8lgm(vn, dirp, name, cred)
        struct vnode *vn;
        struct vnode *dirp;
        char *name;
        struct ucred*cred;
{
        struct vnode *real_vn;
        
        if (!(VOP_REALVP(vn, &real_vn)))
                vn = real_vn;
        return ((real_tmp_link)(vn, dirp, name, cred));
}


int
load_8lgm_tmpfsfix()
{
        int     x;

        x = splhigh();
        real_tmp_link = tmp_vnodeops.vn_link;
        tmp_vnodeops.vn_link = tmp_link_8lgm;
        splx(x);
        return(0);
}


int
unload_8lgm_tmpfsfix()
{
        int     x;

        x = splhigh();
        tmp_vnodeops.vn_link = real_tmp_link;
        splx(x);
        return(0);
}


int
xxxinit(function_code, vdp, vdi, vds)
        unsigned int function_code;
        struct vddrv *vdp;
        addr_t vdi;
        struct vdstat *vds;
{
        bzero(&vd, sizeof(vd));
        vd.Drv_magic = VDMAGIC_PSEUDO;
        vd.Drv_name = "8lgm-tmpfs";

        switch(function_code) {
                case VDLOAD:
                        if (loaded_8lgm) {
                                log(LOG_INFO, "8lgm: tmpfs fix module loaded\n");
                                return(EEXIST);
                        }
                        vdp->vdd_vdtab = (struct vdlinkage*)&vd;
                        load_8lgm_tmpfsfix();
                        loaded_8lgm++;
                        log(LOG_INFO, "8lgm: tmpfs fix module loaded\n");
                        return(0);
                case VDUNLOAD:
                        return (unload(vdp, vdi));
                case VDSTAT:
                        return(0);
                default:
                        return(EIO);
        }
}


static int
unload(vdp, vdi)
        struct vddrv *vdp;
        struct vdioctl_unload *vdi;
{
        if (loaded_8lgm == 0) {
                log(LOG_INFO, "8lgm: tmpfs fix module not loaded!\n");
                return(0);
        }
        unload_8lgm_tmpfsfix();
        loaded_8lgm = 0;
        log(LOG_INFO, "8lgm: tmpfs fix module unloaded\n");
        return(0);
}

8<------------------------- cut here -------------------------

-----------------------------------------------------------------------
$ echo help | mail 8lgm-fileserver () bagpuss demon co uk  (Fileserver help)
8lgm-bugs () bagpuss demon co uk           (To report security flaws)
8lgm-request () bagpuss demon co uk        (Request to be added to list)
8lgm () bagpuss demon co uk                (General enquiries)



Current thread: