Subject: 4.4 BSD issue -- chflags
From: lumpy <lumpy@BLUE.9MM.COM>
List: tech-security
Date: 08/05/1999 19:16:04
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.


	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


	Programmers don't check the return values of calls
	and cause big security holes.


	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.

	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.


	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

	Below is a listing of places to get help for different operating
	systems and products.

	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 for the latest
	information on this issue.  FreeBSD-SA-99:01 is the number of the

	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 has released the following patches:

	(There are two patches there that were spawned from this issue
	 so far.)

	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.

	I have heard some reports that ssh(d) does not properly deal
	with flags set, but have no official feedback.

	They have been notified and I assume they are working on
	a fix to stick in their next release.

	To all the BSD camps and developers who understood and
	fixed/minimized the problem.


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)
-  (void) chown(*namep, real_uid, real_gid);
+  if (chown(*namep, real_uid, real_gid) && !eff_uid)
+    {
+      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)
-  (void) chmod(*namep, TtyMode);
+  if (chmod(*namep, TtyMode) && !eff_uid)
+    {
+      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)
-  (void)chown(*namep, real_uid, real_gid);
+  if (chown(*namep, real_uid, real_gid) && !eff_uid)
+    {
+      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)
-  (void)chmod(*namep, TtyMode);
+  if (chmod(*namep, TtyMode) && !eff_uid)
+    {
+      Msg(errno, "chmod tty");
+      close(f);
+      return -1;
+    }
   return f;