Casinos Not On GamstopNon Gamstop CasinosCasinos Not On GamstopOnline Casinos UKNon Gamstop Casino
26th Aug 1999 [SBWID-116]
COMMAND
	    profil(2)
SYSTEMS AFFECTED
	    NetBSD prior to 1.4.1, Solaris, FreeBSD
PROBLEM
	    Following is  based on  NetBSD Security  Advisory.   NetBSD uses a
	    profil(2) system call that dates  back to "version 6" unix.   This
	    system call arranges for the kernel to sample the PC and increment
	    an element of an array on every profile clock tick.  The  security
	    issue stems from the fact that profiling is not turned off when  a
	    process  execve(2)'s  another  program  image.   As  the  size and
	    location of this array as well  as the scale factor are under  the
	    program's  control,  it  is  possible  to arrange for an arbitrary
	    16-bit program virtual address  to be incremented on  each profile
	    clock tick.
	    Although unlikely, it is  theoretically possible that an  attacker
	    with  local  access  and  knowledge  of  the  addresses  used   by
	    privileged programs could  construct an exploit.   It may be  that
	    there are  no candidate  addresses that,  when incremented, result
	    in a security failure. However, as this can turn -1 into 0, and  0
	    into  1,  and  as   security-related  system  calls  and   library
	    functions often return either -1  or 0, this mechanism could  turn
	    system  call  returns  of  success  into  failure  or failure into
	    success  if  a  program  stores  system  call  results into memory
	    locations.  Discovery of problem and kernel patch by Ross Harvey.
	    Following program  will check  to see  if a  given system  has the
	    profil(2)  bug  described  in  NetBSD  Security  Advisory.   If it
	    prints `Counting!'  then you've  got it...   At least  one  system
	    (Solaris) appears to fix the  security issue but doesn't turn  off
	    profiling unless the new image is  owned by a different user.   To
	    check for this, you need to do something like:
	
		% cc profiltest.c
		% su
		# cp a.out prog.setuid
		# chown (something) prog.setuid
		# (possibly make it setuid)
		# exit
		% ./a.out
	
	    If the program  doesn't find prog.setuid,  it just exec's  itself;
	    this  gets  the  same   result  on  most  systems.    (So:  %   cc
	    profiltest.c; ./a.out).
	
	    #include <sys/types.h>
	    #include <stdio.h>
	    #include <unistd.h>
	    volatile unsigned short twobins[2];
	    int
	    main(int ac, char **av)
	    {
		    if (ac == 1) {
			    /* can't check the return value; on some systems it's void */
			    profil((char *)twobins, sizeof twobins, (u_long)&main, 2);
			    /* try a different image for uid/setuid tests */
			    execl("prog.setuid", "tryroot", "-", 0);
			    /* otherwise, just chain to ourself */
			    execl(av[0], av[0], "-", 0);
			    fprintf(stderr, "problems\n");
			    exit(1);
		    }
		    for(;;) {
			    if (twobins[0] | twobins[1]) {
				    printf("Counting!\n");
				    twobins[0] = twobins[1] = 0;
			    }
		    }
	    }
	
	    Solaris _is_ vulnerable too.  It appears that most or all versions
	    of Solaris  _are_ vulnerable  after all.   Chris Thompson  of  the
	    Cambridge University Computing Service first noticed this and  has
	    notified Sun.
SOLUTION
	    Upgrade to  NetBSD 1.4.1,  NetBSD-current, or  apply the following
	    patch:
	
	    Index: kern_exec.c
	    ===================================================================
	    RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
	    retrieving revision 1.101
	    diff -u -w -u -r1.101 kern_exec.c
	    --- kern_exec.c     1999/04/27 05:28:44     1.101
	    +++ kern_exec.c     1999/08/06 07:19:24
	    @@ -415,6 +415,7 @@
				    goto exec_abort;
		    }
	    +   stopprofclock(p);       /* stop profiling */
		    fdcloseexec(p);             /* handle close on exec */
		    execsigs(p);                /* reset catched signals */
		    p->p_ctxlink = NULL;        /* reset ucontext link */
	
	    The  code  in  FreeBSD  is  somewhat  different  (it  is  actually
	    amazingly close,  given that  the code  was written  twice, by two
	    different parties); patch (not tested) below:
	
	    Index: kern_exec.c
	    ===================================================================
	    RCS file: /home/ncvs/src/sys/kern/kern_exec.c,v
	    retrieving revision 1.99
	    diff -u -r1.99 kern_exec.c
	    --- kern_exec.c	1999/04/27 11:15:55	1.99
	    +++ kern_exec.c	1999/08/11 13:29:28
	    @@ -229,6 +229,9 @@
	     		p->p_fd = tmp;
	     	}
	    +	/* stop profiling */
	    +	stopprofclock(p);
	    +
	 	    /* close files on exec */
	      	fdcloseexec(p);
	
	

Internet highlights