[1531] in linux-security and linux-alert archive

home help back first fref pref prev next nref lref last post

[linux-security] Re: Yet Another DIP Exploit?

daemon@ATHENA.MIT.EDU (Olaf Kirch)
Mon May 5 18:22:29 1997

To: linux-security@redhat.com
Date: Mon, 05 May 1997 14:16:20 +0200
From: Olaf Kirch <okir@monad.swb.de>
Resent-From: linux-security@redhat.com
Reply-To: linux-security@redhat.com


Making dip setuid root creates problems other than buffer overruns etc.
I for one would not allow my users to mess with my routing table.
There are nice things you can do if you fake a SLIP connection to
something that acts as if it was your NIS server, or name server, etc.
Since point-to-point links take precedence over your eth0 network route,
the attacker can redirect all NIS requests to some fake host that spoofs
the appropriate replies.

I can see two reasons for making dip setuid root:

 *	Permit SLIP logins. Easily solved by using sliplogin, which is
	more flexible anyway, IMHO.
 *	Allow users to initiate a SLIP connection. If you really want this,
	either use diald, write a setuid wrapper for dip that calls it
	with the appropriate script, or make dip check that the script
	file is owned by root. Any of these avoid the entire security
	circus altogether. A patch for the latter solution is appended
	below.

Olaf
-- 
Olaf Kirch         |  --- o --- Nous sommes du soleil we love when we play
okir@monad.swb.de  |    / | \   sol.dhoop.naytheet.ah kin.ir.samse.qurax
             For my PGP public key, finger okir@brewhq.swb.de.
------------------------------------------------------------------
--- dip-3.3.7o/main.c.orig	Tue Feb 13 03:03:35 1996
+++ dip-3.3.7o/main.c	Mon May  5 14:13:21 1997
@@ -419,6 +419,10 @@
   /* Are we running in TERMINAL/DIALOG mode? */
   if (opt_t == 1) {
     if (optind != argc) usage();
+    if (getuid() != 0) {
+	fprintf(stderr, "You must be root to use test mode.\n");
+	exit(-1);
+    }
     do_command(stdin);
     /*NOTREACHED*/
   }
@@ -430,22 +434,30 @@
     else sp = path;
   if (strchr(sp, '.') == (char *)NULL) strcat(path, DIP_SFX);
 
-  /* set euid to ruid */
-  if (setreuid(geteuid(), getuid()) != 0){
-   	fprintf(stderr, "dip: setreuid(%d, %d): %s\n", geteuid(), getuid(),
-		strerror(errno));
-	exit(-1);
+  /* Make sure the script file is not writable by anyone but root.
+   * We don't want to let users mess with our routing table.
+   */
+  {
+	struct stat	stb;
+
+	if (stat(path, &stb) < 0) {
+		perror(path);
+		exit(-1);
+	}
+	if (stb.st_uid != 0
+	 || (stb.st_gid != 0 && (stb.st_mode & S_IWGRP))
+	 || (stb.st_mode & S_IWOTH)) {
+		fprintf(stderr,
+			"%s: writable by user/group other than root.\n",
+			path);
+		exit(-1);
+	}
   }
-  /* open file with real uid */
+
+  /* open file */
   if ((fp = fopen(path, "r")) == (FILE *)NULL) {
 	fprintf(stderr, "dip: %s: %s\n", path, strerror(errno));
 	exit(-1);
-  }
-  /* set uids back */
-  if (setreuid(geteuid(), getuid()) != 0){
-        fprintf(stderr, "dip: setreuid(%d, %d): %s\n", geteuid(), getuid(),
-                strerror(errno));
-        exit(-1);
   }
   (void) setbuf(fp, (char *)NULL);
   do_command(fp);


home help back first fref pref prev next nref lref last post