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

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

[linux-security] Re: Vulnrability in all known Linux distributions

daemon@ATHENA.MIT.EDU (Steve Czetty)
Tue Aug 13 11:55:05 1996

From: Steve Czetty <czetts@rpi.edu>
In-reply-to: Your message of "Tue, 13 Aug 1996 07:04:25 EDT."
             <32100CD9.33FBC5AF@mymail.com> 
To: Bugtraq List <BUGTRAQ@netspace.org>, linux-security@tarsier.cv.nrao.edu
Date: Tue, 13 Aug 96 04:15:59 -0500


Hi all, after trying the mount exploit recently posted on Bugtraq, and watching it succeed, I quickly went to my mount source (version 2.5k, I don't know if
there's an newer one or not, I wasn't THAT motivated :-) ) and produced the
following patch.  A 'grep strcpy *.c', 'grep sprintf *.c', and 'grep strcat *.c'
was all I did, so I can't guarantee complete security, but it should be better
than it was before..

The problem in this case happens to be in the libc implementation of 
realpath(), so I plan to post a patch against libc 5.3.12 shortly as well, and
this patch will not be necessary for THIS security hole.  However, considering
the number of calls to strcpy() and the like, I doubt this will be the last
one we will see with mount.

-Steve

----- CUT HERE -----

diff --recursive --unified mount-2.5k/Makefile mount-2.5k-fixed/Makefile
--- mount-2.5k/Makefile	Mon Apr 29 20:25:44 1996
+++ mount-2.5k-fixed/Makefile	Tue Aug 13 03:50:36 1996
@@ -10,7 +10,7 @@
 # For now: a standalone version
 
 CC = gcc
-OPTFLAGS=	-O2 -fomit-frame-pointer
+OPTFLAGS= -O2 -fomit-frame-pointer
 #CFLAGS = -pipe $(OPTFLAGS)
 WARNFLAGS = -Wall -Wstrict-prototypes -Wmissing-prototypes
 #LDFLAGS = -s -N
@@ -64,10 +64,10 @@
 %.o: %.c
 	$(COMPILE) $<
 
-mount: mount.o fstab.o sundries.o version.o $(NFS_OBJS) $(LO_OBJS)
+mount: mount.o fstab.o sundries.o version.o realpath.o $(NFS_OBJS) $(LO_OBJS)
 	$(LINK) $^ $(LDLIBS) -o $@
 
-umount: umount.o fstab.o sundries.o version.o $(LO_OBJS)
+umount: umount.o fstab.o sundries.o version.o realpath.o $(LO_OBJS)
 	$(LINK) $^ $(LDLIBS) -o $@
 
 swapon:	swapon.o fstab.o version.o
Only in mount-2.5k-fixed/h: loop.h.orig
diff --recursive --unified mount-2.5k/lomount.c mount-2.5k-fixed/lomount.c
--- mount-2.5k/lomount.c	Mon May  6 10:05:10 1996
+++ mount-2.5k-fixed/lomount.c	Tue Aug 13 03:41:06 1996
@@ -95,7 +95,7 @@
     FILE *procdev;
 
     for(i = 0; ; i++) {
-      sprintf(dev, "/dev/loop%d", i);
+      snprintf(dev, 20, "/dev/loop%d", i);
       if (stat (dev, &statbuf) == 0 && S_ISBLK(statbuf.st_mode)) {
 	somedev++;
 	fd = open (dev, O_RDONLY);
Only in mount-2.5k-fixed/: mount-exploit.c
diff --recursive --unified mount-2.5k/nfsmount.c mount-2.5k-fixed/nfsmount.c
--- mount-2.5k/nfsmount.c	Sun Mar 24 10:52:02 1996
+++ mount-2.5k-fixed/nfsmount.c	Tue Aug 13 03:04:20 1996
@@ -108,7 +108,7 @@
 
 	msock = fsock = -1;
 	mclient = NULL;
-	strcpy(hostdir, spec);
+	strncpy(hostdir, spec, 1024);
 	if ((s = (strchr(hostdir, ':')))) {
 		hostname = hostdir;
 		dirname = s + 1;
@@ -140,7 +140,7 @@
 	old_opts = *extra_opts;
 	if (!old_opts)
 		old_opts = "";
-	sprintf(new_opts, "%s%saddr=%s",
+	snprintf(new_opts, 1024, "%s%saddr=%s",
 		old_opts, *old_opts ? "," : "",
 		inet_ntoa(server_addr.sin_addr));
 	*extra_opts = xstrdup(new_opts);
@@ -492,7 +492,7 @@
 		if (nfs_errtbl[i].stat == stat)
 			return strerror(nfs_errtbl[i].errno);
 	}
-	sprintf(buf, "unknown nfs status return value: %d", stat);
+	snprintf(buf, 256, "unknown nfs status return value: %d", stat);
 	return buf;
 }
 
diff --recursive --unified mount-2.5k/realpath.c mount-2.5k-fixed/realpath.c
--- mount-2.5k/realpath.c	Sat Mar 11 20:39:59 1995
+++ mount-2.5k-fixed/realpath.c	Tue Aug 13 03:51:24 1996
@@ -79,7 +79,7 @@
 	int n;
 
 	/* Make a copy of the source path since we may need to modify it. */
-	strcpy(copy_path, path);
+	strncpy(copy_path, path, PATH_MAX);
 	path = copy_path;
 	max_path = copy_path + PATH_MAX - 2;
 	/* If it's a relative pathname use getwd for starters. */
@@ -161,8 +161,8 @@
 				return NULL;
 			}
 			/* Insert symlink contents into path. */
-			strcat(link_path, path);
-			strcpy(copy_path, link_path);
+			strncat(link_path, path, (PATH_MAX - strlen(link_path)));
+			strncpy(copy_path, link_path, PATH_MAX);
 			path = copy_path;
 		}
 #endif /* S_IFLNK */
diff --recursive --unified mount-2.5k/sundries.c mount-2.5k-fixed/sundries.c
--- mount-2.5k/sundries.c	Tue Apr 23 14:37:35 1996
+++ mount-2.5k-fixed/sundries.c	Tue Aug 13 03:34:15 1996
@@ -354,10 +354,10 @@
   
   if (path == NULL)
     return NULL;
-  
+ 
   if (realpath (path, canonical))
     return canonical;
 
-  strcpy (canonical, path);
+  strncpy (canonical, path, (PATH_MAX + 1));
   return canonical;
 }
diff --recursive --unified mount-2.5k/umount.c mount-2.5k-fixed/umount.c
--- mount-2.5k/umount.c	Tue Apr 23 14:34:05 1996
+++ mount-2.5k-fixed/umount.c	Tue Aug 13 03:32:56 1996
@@ -67,12 +67,12 @@
       char hostname[MAXHOSTNAMELEN];
       char dirname[1024];
 
-      strcpy(buffer,spec);
+      strncpy(buffer,spec,256);
               /* spec is constant so must use own buffer */
       if((p = strchr(buffer,':'))) {
               *p = '\0';
-              strcpy(hostname, buffer);
-              strcpy(dirname, p+1);
+              strncpy(hostname, buffer, 256);
+              strncpy(dirname, p+1, 1024);
 #ifdef DEBUG
               printf("host: %s, directory: %s\n", hostname, dirname);
 #endif

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