[ Search ] [ What's New? ] [ About ]
[ Bugs ] [ Misc ] [ Mailing Lists ] [ Newgroups ] [ NewsWire ] [ Papers ] [ People ]
[ Pictures ] [ Publications ] [ Responce Teams ] [ Tools ] [ Upcoming Events ] [ Web Sites ]

tmpfs(4)
Systems Affected:SunOS 4.1.x
Problem: Unprivileged users can panic the SunOS 4.1.x kernel if the TMPFS filesystem is in use.

Assuming /tmp is a tmpfs filesystem:

	% cd /tmp
	% /usr/etc/mknod fifo p
	% ln fifo link
	% ls -ClFg link fifo
The problem actually occurs with any 'special' file on the tmpfs filesystem. tmp_link() incorrectly updates the link count (va_nlink in struct vattr) in the snode's vnode rather than in the real vnode.
Solution:
  • Contact your vendor for a patch.

  • In the meantime either install the workaround given below, or avoid using TMPFS mounted filesystems.

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 8lgm_tmpfs.c * modload 8lgm_tmpfs.o */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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); }

Aleph One / aleph1@underground.org
Copyright © 1996 Computer Underground Society. All rights reserved.