Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 5 Aug 1999 19:46:35 -0400 (EDT)
From:      "Brian F. Feldman" <green@FreeBSD.org>
To:        hackers@FreeBSD.org
Subject:   more crashes and fixes (linux/svr4/ibcs2)
Message-ID:  <Pine.BSF.4.10.9908051928210.84441-100000@janus.syracuse.net>

next in thread | raw e-mail | index | archive | help
   Thanks to our Peter Holm's stress testing suite, I found a pretty bad
bug in all current emulation (*) code. They all share a common base, and
the problem is in the pathname translation code.
   What it amounts to is the inherent assumption that all passed in paths
are valid addresses. This is not true, and the problem occurs when the
stackgap memory (used when we pass the path to good ol' namei/NDINIT)
does not contain valid data. This can happen very easily:
        1. A bad address is passed to the kernel with a syscall, i.e.
           linux_uselib().
        2. Linux_uselib() calls a macro which calls linux_emul_find().
        3. Linux_emul_find() notices that the address is invalid
           (via return of EFAULT from copyinstr()) and returns that.
        4. The code ignores the error and continues on its merry way,
           assuming that the stackgap contains valid data, but it
           will only get to problems. namei() will crash when it
           gets a page fault trying to copyinstr() from UIO_SYSSPACE.
   Here's my fix:

--- src/sys/i386/linux/linux_util.h.orig	Thu Aug  5 18:32:02 1999
+++ src/sys/i386/linux/linux_util.h	Thu Aug  5 19:03:27 1999
@@ -83,10 +83,17 @@
 int linux_emul_find __P((struct proc *, caddr_t *, const char *, char *,
 			char **, int));
 
-#define CHECKALTEXIST(p, sgp, path) \
-    linux_emul_find(p, sgp, linux_emul_path, path, &(path), 0)
+#define CHECKALT(p, sgp, path, i) 					\
+	do {								\
+		int _error;						\
+									\
+		_error = linux_emul_find(p, sgp, linux_emul_path, path,	\
+		    &path, i);						\
+		if (_error)						\
+			return (_error);				\
+	} while (0)
 
-#define CHECKALTCREAT(p, sgp, path) \
-    linux_emul_find(p, sgp, linux_emul_path, path, &(path), 1)
+#define CHECKALTEXIST(p, sgp, path) CHECKALT(p, sgp, path, 0)
+#define CHECKALTCREAT(p, sgp, path) CHECKALT(p, sgp, path, 1)
 
 #endif /* !_LINUX_UTIL_H_ */

   Either this or a similar fix will be necessary for svr4, ibcs2, and linux.

(*) I said emulation because we are emulating the ABI for another OS.
    Therefore, linux.ko, svr4.ko, and ibcs2*.ko are all "emulators."

 Brian Fundakowski Feldman      _ __ ___ ____  ___ ___ ___  
 green@FreeBSD.org                   _ __ ___ | _ ) __|   \ 
     FreeBSD: The Power to Serve!        _ __ | _ \._ \ |) |
       http://www.FreeBSD.org/              _ |___/___/___/ 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.10.9908051928210.84441-100000>