Casinos Not On GamstopNon Gamstop CasinosCasinos Not On GamstopOnline Casinos UKNon Gamstop Casino
31th Oct 1997 [SBWID-176]
COMMAND
	    open()
SYSTEMS AFFECTED
	    FreeBSD 2.1.*, FreeBSD 2.2.*, FreeBSD-stable and  FreeBSD-current,
	    NetBSD, OpenBSD
PROBLEM
	    In  FreeBSD,  the  open()  system  call  is  used  in  normal file
	    operations.  When calling open(), the caller should specify if the
	    file is to be  opened for reading, for  writing or for both.   The
	    right to reading  from and/or writing  to a file  is controlled by
	    the file's  mode bits  in the  filesystem.   In FreeBSD, open() is
	    also used to obtain the right to do privileged io instructions.
	    A  problem  exists  in  the  open()  syscall that allows processes
	    to obtain  a valid  file descriptor  without having  read or write
	    permissions  on  the  file  being  opened.  This is normally not a
	    problem.  The  FreeBSD  way  of  obtaining  the  right  to  do  io
	    instructions however,  is based  on the  right to  open a specific
	    file  (/dev/io).   The  problem  can  be  used  by any user on the
	    system to do unauthorised io instructions.
	    This is a pretty serious hole in open() and permissions...   Note,
	    in  the  following,  open()  succeeds,  and  ioctls  are  probably
	    executed...  This was posted by explorer.
	
	    /*
	     * This will give you a file descriptor on a device you should not
	     * have access  to.  This  seems really, really  screwed up, since
	     * holding a fd lets you do a lot of ioctls that you should not be
	     * able to do...
	     */
	    #include <fcntl.h>
	    #include <stdio.h>
	    #include <unistd.h>
	    #include <err.h>
	    int
	    main(int argc, char **argv)
	    {
	      int fd;
	      fd = open("/dev/rsd0a", -1, 0);
	      if (fd < 0)
	      err(1, "open");
	    }
	
	    This is a variant  of a bug Theo  de Raadt found in  SunOS back in
	    the 1980s.  The  basic issue is that  the code that guards  access
	    to the device-specific open() routine checks explicitly for FREAD,
	    FWRITE, and O_TRUNC, and passes the call through if none of  these
	    are set.  Theo's bug involved using "3" for the open() flag.
	    The problem here is that before calls to open() are even passed to
	    the vnode  open() routine  (after the  vnode is  looked up  by the
	    generic vfs_syscalls open() syscall  handler), the flags field  is
	    incremented by one:
	
	    vfs_syscalls.c:open()
	            ...
	            flags = FFLAGS(uap->flags);
	            ...
	    where FFLAGS() is:
	    ./sys/fcntl.h:#define  FFLAGS(oflags)  ((oflags) + 1)
	
	    As you can see,  passing a "-1" to  open() will result in  "flags"
	    becoming "0"  - open()  ordinarily never  passes "0"  to the vnode
	    code,  since  "0"  becomes  "1"  after  being  converted to fflags
	    format.
	    A fun game you can play with practically no programming ability is
	    to exploit the fact  that some devices will  initialize themselves
	    immediately upon being opened  - particularly amusing is  the SCSI
	    tape driver, sys/scsi/st.c, which will rewind itself when  opened.
	    Simply run  the previously  posted example  code on  /dev/rst0 and
	    destroy tonight's backup.
SOLUTION
	    You may want to get closer look ar FreeBSD patch:
	
	        ftp://freebsd.org/pub/CERT/patches/SA-97:05/
	
	

Internet highlights