From owner-freebsd-hackers Thu Aug 5 16:46:35 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from janus.syracuse.net (janus.syracuse.net [205.232.47.15]) by hub.freebsd.org (Postfix) with ESMTP id 0DB9415650 for ; Thu, 5 Aug 1999 16:46:30 -0700 (PDT) (envelope-from green@FreeBSD.org) Received: from localhost (green@localhost) by janus.syracuse.net (8.9.3/8.8.7) with ESMTP id TAA84788 for ; Thu, 5 Aug 1999 19:46:35 -0400 (EDT) X-Authentication-Warning: janus.syracuse.net: green owned process doing -bs Date: Thu, 5 Aug 1999 19:46:35 -0400 (EDT) From: "Brian F. Feldman" X-Sender: green@janus.syracuse.net To: hackers@FreeBSD.org Subject: more crashes and fixes (linux/svr4/ibcs2) Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG 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