Hello,

On Mon, Nov 24, 2008 at 08:01:42AM +1100, [EMAIL PROTECTED] wrote:
> 
> Seems your message relates to "old" things, Nicolas has fixed this for
> lenny already.

I've made an upload to fix #505271, but not this bug (#505071).
The answer on debian-release was not enough for me to also fix #505071.

> Please also:
>  - fix for etch,

I made an upload for Etch (-7etch1, also to fix #505271)
Moritz, if you can't see it, maybe I did it wrong.

>  - alert other Linux distros,

A new upstream version was released this weekend.

It also contains a fix for this bug (#505071).
I attach this patch in case it is considered OK and needed for Lenny.

>  - issue DSA.

This will be done by the Security Team when the Etch package will be ready
on all archs.

Best Regards,
-- 
Nekral
Index: 4.1.2.2/libmisc/chowntty.c
===================================================================
--- 4.1.2.2/libmisc/chowntty.c	(révision 2449)
+++ 4.1.2.2/libmisc/chowntty.c	(révision 2459)
@@ -44,29 +44,12 @@
 #include <pwd.h>
 #include "getdef.h"
 /*
- * is_my_tty -- determine if "tty" is the same as TTY stdin is using
- */
-static int is_my_tty (const char *tty)
-{
-	struct stat by_name, by_fd;
-
-	if (stat (tty, &by_name) || fstat (0, &by_fd))
-		return 0;
-
-	if (by_name.st_rdev != by_fd.st_rdev)
-		return 0;
-	else
-		return 1;
-}
-
-/*
  *	chown_tty() sets the login tty to be owned by the new user ID
  *	with TTYPERM modes
  */
 
-void chown_tty (const char *tty, const struct passwd *info)
+void chown_tty (const struct passwd *info)
 {
-	char buf[200], full_tty[200];
 	char *group;		/* TTY group name or number */
 	struct group *grent;
 	gid_t gid;
@@ -90,24 +73,11 @@
 	 * the group as determined above.
 	 */
 
-	if (*tty != '/') {
-		snprintf (full_tty, sizeof full_tty, "/dev/%s", tty);
-		tty = full_tty;
-	}
-
-	if (!is_my_tty (tty)) {
-		SYSLOG ((LOG_WARN,
-			 "unable to determine TTY name, got %s\n", tty));
-		closelog ();
-		exit (1);
-	}
-
 	if (fchown (STDIN_FILENO, info->pw_uid, gid) ||
 	    fchmod (STDIN_FILENO, getdef_num ("TTYPERM", 0600))) {
 		int err = errno;
 
-		snprintf (buf, sizeof buf, _("Unable to change tty stdin"));
-		perror (buf);
+		perror (_("Unable to change tty stdin"));
 		SYSLOG ((LOG_WARN,
 			 "unable to change tty stdin for user `%s'\n",
 			 info->pw_name));
Index: 4.1.2.2/libmisc/utmp.c
===================================================================
--- 4.1.2.2/libmisc/utmp.c	(révision 2449)
+++ 4.1.2.2/libmisc/utmp.c	(révision 2459)
@@ -57,6 +57,30 @@
 	_("Unable to determine your tty name.")
 
 /*
+ * is_my_tty -- determine if "tty" is the same TTY stdin is using
+ */
+static int is_my_tty (const char *tty)
+{
+	char full_tty[200];
+	struct stat by_name, by_fd;
+
+	if ('/' != *tty) {
+		snprintf (full_tty, sizeof full_tty, "/dev/%s", tty);
+		tty = full_tty;
+	}
+
+	if ((stat (tty, &by_name) != 0) || (fstat (STDIN_FILENO, &by_fd) != 0)) {
+		return 0;
+	}
+
+	if (by_name.st_rdev != by_fd.st_rdev) {
+		return 0;
+	} else {
+		return 1;
+	}
+}
+
+/*
  * checkutmp - see if utmp file is correct for this process
  *
  *	System V is very picky about the contents of the utmp file
@@ -84,7 +108,8 @@
 	while ((ut = getutent ()))
 		if (ut->ut_pid == pid && ut->ut_line[0] && ut->ut_id[0] &&
 		    (ut->ut_type == LOGIN_PROCESS
-		     || ut->ut_type == USER_PROCESS))
+		     || ut->ut_type == USER_PROCESS) &&
+		    is_my_tty (ut->ut_line))
 			break;
 
 	/* If there is one, just use it, otherwise create a new one.  */
Index: 4.1.2.2/ChangeLog
===================================================================
--- 4.1.2.2/ChangeLog	(révision 2449)
+++ 4.1.2.2/ChangeLog	(révision 2459)
@@ -2,6 +2,14 @@
 
 	* NEWS, libmisc/chowntty.c: Fix a race condition that could lead
 	to gaining ownership or changing mode of arbitrary files.
+	* NEWS, libmisc/chowntty.c, libmisc/utmp.c: is_my_tty() moved from
+	utmp.c to chowntty.c. checkutmp() now only uses an existing utmp
+	entry if the pid matches and ut_line matches with the current tty.
+	This fixes a possible DOS when entries can be forged in the utmp
+	file.
+	* libmisc/chowntty.c, src/login.c, lib/prototypes.h: Remove the 
+	tty argument from chown_tty. chown_tty always changes stdin and
+	does not need this argument anymore.
 
 2008-06-26  Nicolas François  <[EMAIL PROTECTED]>
 
Index: 4.1.2.2/src/login.c
===================================================================
--- 4.1.2.2/src/login.c	(révision 2449)
+++ 4.1.2.2/src/login.c	(révision 2459)
@@ -1005,7 +1005,7 @@
 	}
 	setup_limits (&pwent);	/* nice, ulimit etc. */
 #endif				/* ! USE_PAM */
-	chown_tty (tty, &pwent);
+	chown_tty (&pwent);
 
 #ifdef USE_PAM
 	/*
Index: 4.1.2.2/lib/prototypes.h
===================================================================
--- 4.1.2.2/lib/prototypes.h	(révision 2449)
+++ 4.1.2.2/lib/prototypes.h	(révision 2459)
@@ -73,7 +73,7 @@
 extern int chown_tree (const char *, uid_t, uid_t, gid_t, gid_t);
 
 /* chowntty.c */
-extern void chown_tty (const char *, const struct passwd *);
+extern void chown_tty (const struct passwd *);
 
 /* console.c */
 extern int console (const char *);
Index: 4.1.2.2/NEWS
===================================================================
--- 4.1.2.2/NEWS	(révision 2449)
+++ 4.1.2.2/NEWS	(révision 2459)
@@ -5,6 +5,8 @@
 *** security
 - Fix a race condition in login that could lead to gaining ownership or
   changing mode of arbitrary files.
+- Fix a possible login DOS, which could be caused by injecting forged 
+  entries in utmp.
 
 shadow-4.1.2 -> shadow-4.1.2.1						26-06-2008
 

Reply via email to