4.4 BSD issue -- chflags

From: lumpy (lumpyat_private)
Date: Thu Aug 05 1999 - 16:16:04 PDT

  • Next message: Ryan Permeh: "Re: bo2k plugins"

    note: I drafted this advisory last week after I found the hole, and decided
    	not to post it until I got some vendor feedback so that I could
    	properly alert people about how to actually fix the problem.
    
    ---<snip>---
    
    Title:
    	BSD File Flags and Programming Techniques
    
    Systems Affected:
    
    	4.4BSD based operating systems.
    	A majority of the programs that implement a method of login
    	on 4.4BSD based operating systems.
    
    	Patches to the following are listed
    	at the end of the advisory:
    
    		FreeBSD, OpenBSD, NetBSD, BSD/OS
    
    	Status information on the following are
    	listed at the end of the advisory:
    
    		SSH, XFree86, screen
    
    Synopsis:
    
    	Programmers don't check the return values of calls
    	and cause big security holes.
    
    Description:
    
    	Several security holes have been found to be the result
    	of programmers not checking the return values of their
    	system calls.
    
    	This is because programmers often times think that its
    	"ok" to make system calls like chmod() and chown() as root
    	and not check the return because they believe that their
    	superuser status allows them to override all possible
    	user attributes.
    
    	One such condition that might make chmod() or chown() fail
    	even if you are the superuser is if there are BSD file flags
    	set.  The superuser must explicitly clear these such flags
    	as user append-only and user immutable before these system
    	calls will succeed.
    
    Impact:
    	
    	There are several implications of the problem.  They range from
    	Denial of Service attacks to actual exploitation.
    
    Example 1:
    
    	The impact of not checking that your chmod() or chown()
    	worked is made very clear when looking at getty and login.
    
    	Because getty and login don't check the returns of their
    	chmod()/chown(), its possible for a user to either
    	create an attack based in the fact that you can own another
    	users' tty or denial of service attack the system.
    
    	To setup a trap so that you own someone elses tty, for instance,
    	a user can log in, chmod 777 `tty`, chflags uappnd `tty`, and then
    	log out.  The next user to log into that tty will, on most BSDs
    	checked, find that their tty is still owned by the original user.
    
    Example 2:
    
    	Another example is with /etc/rc, which is executed in securelevel 0,
    	where /tmp is cleared out.  On systems that have a real (non-mfs)
    	/tmp directory, /etc/rc will not always properly clear the
    	directory out when if it attempts to.
    
    	The point is that non device operations are also affected by this.
    
    Fixes:
    
    	Being that this is not exactly "one exploitable hole", but rather
    	a type of security hole based purely on unsafe programming, it is
    	hard to specifically point out one place for a fix.
    
    	The tty issue being probably one of the worst examples of this
    	behavior has caused several patches to be released.  Some attempts
    	at fixing the bug are more complete than others.  Obviously
    	several userland modifications must be made to fully wipe out this
    	problem.
    
    	Below is a listing of places to get help for different operating
    	systems and products.
    
    
    FreeBSD
    	
    	FreeBSD has corrected the problems noted in this advisory as of Wed
    	Aug 5 for -current, 3.2-stable, and 2.2.8-stable.  an advisory from
    	the FreeBSD security officer will be forthcoming with patches for each
    	branch.  Please see http://www.freebsd.org/security/ for the latest
    	information on this issue.  FreeBSD-SA-99:01 is the number of the
    	advisory.
    
    NetBSD
    	Only NetBSD/current has been fixed.
    	Two fixes have been committed and they are in:
    	$NetBSD: vfs_syscalls.c,v 1.146 1999/07/31 03:18:43 christos Exp $
    	$NetBSD: rc,v 1.128 1999/08/05 20:51:57 christos Exp $
    
    BSDI
    	BSDI has released the following patches:
    	ftp://ftp.bsdi.com/bsdi/patches/patches-4.0.1/M401-014
    	ftp://ftp.bsdi.com/bsdi/patches/patches-3.1/M310-056
    
    
    OpenBSD
    	http://www.openbsd.org/security.html#25
    	(There are two patches there that were spawned from this issue
    	 so far.)
    
    Screen
    	After contacting the authors of screen, they have provided
    	patches for the current	releases (screen-3.7.6 and screen-3.9.2).
    	They are at the bottom of this advisory.
    
    SSH
    	I have heard some reports that ssh(d) does not properly deal
    	with flags set, but have no official feedback.
    
    XFree
    	They have been notified and I assume they are working on
    	a fix to stick in their next release.
    
    
    Thanks:
    	To all the BSD camps and developers who understood and
    	fixed/minimized the problem.
    
    
    ---<snip>---
    
    
    
    Patch for screen-3.7.6:
    --- window.c.orig	Thu Aug  5 19:35:46 1999
    +++ window.c	Thu Aug  5 19:40:01 1999
    @@ -447,15 +447,25 @@
         return f;
    
     #ifdef PTYGROUP
    -  (void) chown(*namep, real_uid, PTYGROUP);
    +  if (chown(*namep, real_uid, PTYGROUP) && !eff_uid)
     #else
    -  (void) chown(*namep, real_uid, real_gid);
    +  if (chown(*namep, real_uid, real_gid) && !eff_uid)
     #endif
    +    {
    +      Msg(errno, "chown tty");
    +      close(f);
    +      return -1;
    +    }
     #ifdef UTMPOK
    -  (void) chmod(*namep, lflag ? TtyMode : (TtyMode & ~022));
    +  if (chmod(*namep, lflag ? TtyMode : (TtyMode & ~022)) && !eff_uid)
     #else
    -  (void) chmod(*namep, TtyMode);
    +  if (chmod(*namep, TtyMode) && !eff_uid)
     #endif
    +    {
    +      Msg(errno, "chmod tty");
    +      close(f);
    +      return -1;
    +    }
       return f;
     }
    
    
    Patch for screen-3.9.2:
    --- window.c.orig	Thu Aug  5 19:42:16 1999
    +++ window.c	Thu Aug  5 19:43:14 1999
    @@ -1012,15 +1012,25 @@
         return f;
    
     #ifdef PTYGROUP
    -  (void)chown(*namep, real_uid, PTYGROUP);
    +  if (chown(*namep, real_uid, PTYGROUP) && !eff_uid)
     #else
    -  (void)chown(*namep, real_uid, real_gid);
    +  if (chown(*namep, real_uid, real_gid) && !eff_uid)
     #endif
    +    {
    +      Msg(errno, "chown tty");
    +      close(f);
    +      return -1;
    +    }
     #ifdef UTMPOK
    -  (void)chmod(*namep, lflag ? TtyMode : (TtyMode & ~022));
    +  if (chmod(*namep, lflag ? TtyMode : (TtyMode & ~022)) && !eff_uid)
     #else
    -  (void)chmod(*namep, TtyMode);
    +  if (chmod(*namep, TtyMode) && !eff_uid)
     #endif
    +    {
    +      Msg(errno, "chmod tty");
    +      close(f);
    +      return -1;
    +    }
       return f;
     }
    



    This archive was generated by hypermail 2b30 : Fri Apr 13 2001 - 14:55:07 PDT