3571e53040
patches for easier mirroring, to eliminate a special copy, to make www.freebsd.org/security a full copy of security.freebsd.org and be eventually be the same. For now files are just sitting there. The symlinks are missing. Discussed on: www (repository location) Discussed with: simon (so)
194 lines
6.2 KiB
Text
194 lines
6.2 KiB
Text
-----BEGIN PGP SIGNED MESSAGE-----
|
|
|
|
=============================================================================
|
|
FreeBSD-SA-00:42 Security Advisory
|
|
FreeBSD, Inc.
|
|
|
|
Topic: Linux binary compatability mode can cause system compromise
|
|
|
|
Category: core
|
|
Module: kernel
|
|
Announced: 2000-08-28
|
|
Credits: Boris Nikolaus <boris@cs.tu-berlin.de>
|
|
Affects: FreeBSD 3.x, 4.x and 5.x prior to the correction date
|
|
Corrected: 2000-07-23 (FreeBSD 5.0-CURRENT)
|
|
2000-07-29 (FreeBSD 4.1-STABLE)
|
|
2000-08-24 (FreeBSD 3.5-STABLE)
|
|
FreeBSD only: Yes
|
|
|
|
I. Background
|
|
|
|
FreeBSD is binary-compatible with the Linux operating system through a
|
|
loadable kernel module/optional kernel component.
|
|
|
|
II. Problem Description
|
|
|
|
The linux binary-compatability module implements a "shadow" filesystem
|
|
hierarchy rooted in /compat/linux, which is overlayed against the
|
|
regular filesystem hierarchy so that Linux binaries "see" files in the
|
|
shadow hierarchy which can mask the native files.
|
|
|
|
Filenames in this shadow hierarchy are treated incorrectly by the
|
|
linux kernel module under certain circumstances, and a kernel stack
|
|
overflow leading to a system compromise by an unprivileged user may be
|
|
possible when very long filenames are used. This is only possible when
|
|
the linux kernel module is loaded, or the equivalent functionality is
|
|
statically compiled into the kernel. It is not enabled by default.
|
|
|
|
This vulnerability was fixed just after the release of FreeBSD
|
|
4.1-RELEASE, and 3.5-RELEASE is also vulnerable.
|
|
|
|
III. Impact
|
|
|
|
Local users may be able to obtain root privileges on the system when
|
|
linux compatability mode is enabled.
|
|
|
|
IV. Workaround
|
|
|
|
To determine whether the linux compatability module has been loaded,
|
|
execute the following command as root and look for a 'linux.ko' entry:
|
|
|
|
# kldstat
|
|
Id Refs Address Size Name
|
|
1 7 0xc0100000 270be0 kernel
|
|
2 1 0xc0371000 5540 vesa.ko
|
|
3 1 0xc0377000 10094 randomdev.ko
|
|
4 1 0xc0e17000 4e000 nfs.ko
|
|
5 1 0xc0e83000 11000 linux.ko
|
|
|
|
If present, unload the "linux" module by executing the following
|
|
command as root:
|
|
|
|
# kldunload linux
|
|
|
|
For safety, remove the /modules/linux.ko file to prevent it being
|
|
reloaded accidentally, and add or change the following line in
|
|
/etc/rc.conf:
|
|
|
|
linux_enable="NO" # Linux binary compatibility loaded at startup (or NO).
|
|
|
|
If the module is not loaded, to determine whether the functionality
|
|
has been statically compiled into the kernel, check the kernel
|
|
configuration file for the following line:
|
|
|
|
options COMPAT_LINUX
|
|
|
|
If present, remove and recompile the kernel as described in
|
|
http://www.freebsd.org/handbook/kernelconfig.html and reboot the
|
|
system.
|
|
|
|
V. Solution
|
|
|
|
One of the following:
|
|
|
|
1) Upgrade your vulnerable FreeBSD system to 3.5-STABLE, 4.1-STABLE or
|
|
5.0-CURRENT after the respective correction dates.
|
|
|
|
2) Apply the patch below and recompile your kernel.
|
|
|
|
Either save this advisory to a file, or download the patch and
|
|
detached PGP signature from the following locations, and verify the
|
|
signature using your PGP utility.
|
|
|
|
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-00:42/linux.patch
|
|
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-00:42/linux.patch.asc
|
|
|
|
# cd /usr/src/sys/i386/linux
|
|
# patch -p < /path/to/patch_or_advisory
|
|
|
|
[ Recompile your kernel as described in
|
|
http://www.freebsd.org/handbook/kernelconfig.html and reboot the
|
|
system ]
|
|
|
|
Index: linux_misc.c
|
|
===================================================================
|
|
RCS file: /home/ncvs/src/sys/i386/linux/linux_misc.c,v
|
|
retrieving revision 1.77.2.3
|
|
retrieving revision 1.77.2.4
|
|
diff -u -r1.77.2.3 -r1.77.2.4
|
|
--- linux_misc.c 2000/07/20 05:31:56 1.77.2.3
|
|
+++ linux_misc.c 2000/07/30 05:36:11 1.77.2.4
|
|
@@ -954,6 +954,8 @@
|
|
tv[1].tv_usec = 0;
|
|
/* so that utimes can copyin */
|
|
tvp = (struct timeval *)stackgap_alloc(&sg, sizeof(tv));
|
|
+ if (tvp == NULL)
|
|
+ return (ENAMETOOLONG);
|
|
if ((error = copyout(tv, tvp, sizeof(tv))))
|
|
return error;
|
|
bsdutimes.tptr = tvp;
|
|
Index: linux_util.c
|
|
===================================================================
|
|
RCS file: /home/ncvs/src/sys/i386/linux/linux_util.c,v
|
|
retrieving revision 1.9.2.1
|
|
retrieving revision 1.9.2.2
|
|
diff -u -r1.9.2.1 -r1.9.2.2
|
|
--- linux_util.c 2000/07/07 01:23:45 1.9.2.1
|
|
+++ linux_util.c 2000/07/30 05:36:11 1.9.2.2
|
|
@@ -162,7 +162,10 @@
|
|
else {
|
|
sz = &ptr[len] - buf;
|
|
*pbuf = stackgap_alloc(sgp, sz + 1);
|
|
- error = copyout(buf, *pbuf, sz);
|
|
+ if (*pbuf != NULL)
|
|
+ error = copyout(buf, *pbuf, sz);
|
|
+ else
|
|
+ error = ENAMETOOLONG;
|
|
free(buf, M_TEMP);
|
|
}
|
|
|
|
Index: linux_util.h
|
|
===================================================================
|
|
RCS file: /home/ncvs/src/sys/i386/linux/linux_util.h,v
|
|
retrieving revision 1.10
|
|
retrieving revision 1.10.2.1
|
|
diff -u -r1.10 -r1.10.2.1
|
|
--- linux_util.h 1999/12/04 11:10:22 1.10
|
|
+++ linux_util.h 2000/07/30 05:36:11 1.10.2.1
|
|
@@ -56,29 +56,27 @@
|
|
static __inline caddr_t stackgap_init(void);
|
|
static __inline void *stackgap_alloc(caddr_t *, size_t);
|
|
|
|
+#define szsigcode (*(curproc->p_sysent->sv_szsigcode))
|
|
+
|
|
static __inline caddr_t
|
|
stackgap_init()
|
|
{
|
|
-#define szsigcode (*(curproc->p_sysent->sv_szsigcode))
|
|
return (caddr_t)(PS_STRINGS - szsigcode - SPARE_USRSPACE);
|
|
}
|
|
|
|
-
|
|
static __inline void *
|
|
stackgap_alloc(sgp, sz)
|
|
caddr_t *sgp;
|
|
size_t sz;
|
|
{
|
|
- void *p = (void *) *sgp;
|
|
- *sgp += ALIGN(sz);
|
|
+ void *p = (void *) *sgp;
|
|
+
|
|
+ sz = ALIGN(sz);
|
|
+ if (*sgp + sz > (caddr_t)(PS_STRINGS - szsigcode))
|
|
+ return NULL;
|
|
+ *sgp += sz;
|
|
return p;
|
|
}
|
|
-
|
|
-#ifdef DEBUG_LINUX
|
|
-#define DPRINTF(a) printf a;
|
|
-#else
|
|
-#define DPRINTF(a)
|
|
-#endif
|
|
|
|
extern const char linux_emul_path[];
|
|
|
|
-----BEGIN PGP SIGNATURE-----
|
|
Version: 2.6.2
|
|
|
|
iQCVAwUBOaq1wFUuHi5z0oilAQFcVQQAlYhhDM6T/qEDqVTvG9yr9mv++LVGqqRE
|
|
SI4MEbmwbV5NvmFqTM2OzGpKsUaAy9gEfA5mjVKR+PRFoY7g68heFGAKWSRHmgs5
|
|
ramrzVxBHOeviaHeAXpH7LgJOdFo8EwhqehLtv+M0I5n9JJjPvAEWXG9cdiYXTto
|
|
pKJAPVXr9NU=
|
|
=r8gN
|
|
-----END PGP SIGNATURE-----
|