Bugtraq mailing list archives

Re: Vulnrability in all known Linux distributions


From: czetts () rpi edu (Steve Czetty)
Date: Tue, 13 Aug 1996 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



Current thread: