[179] in bugtraq
tmpfs panic fix - was Re: udp packet storms - ping death
daemon@ATHENA.MIT.EDU ([8LGM] Security Team)
Sat Nov 5 20:26:41 1994
From: "[8LGM] Security Team" <8lgm@bagpuss.demon.co.uk>
To: dawagner@phoenix.Princeton.EDU
Date: Sat, 5 Nov 1994 21:04:49 +0000 (GMT)
Cc: bugtraq@fc.net, chowes@helix.net
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)