[3128] in bugtraq
Re: Vulnrability in all known Linux distributions
daemon@ATHENA.MIT.EDU (Steve Czetty)
Tue Aug 13 04:39:19 1996
Date: Tue, 13 Aug 1996 04:15:59 -0500
Reply-To: Bugtraq List <BUGTRAQ@NETSPACE.ORG>
From: Steve Czetty <czetts@rpi.edu>
X-To: linux-security@tarsier.cv.nrao.edu
To: Multiple recipients of list BUGTRAQ <BUGTRAQ@NETSPACE.ORG>
In-Reply-To: Your message of "Tue, 13 Aug 1996 07:04:25 EDT."
<32100CD9.33FBC5AF@mymail.com>
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