[1531] in linux-security and linux-alert archive
[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);