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)
284 lines
9.9 KiB
Text
284 lines
9.9 KiB
Text
-----BEGIN PGP SIGNED MESSAGE-----
|
|
|
|
=============================================================================
|
|
FreeBSD-SA-99:04 Security Advisory
|
|
FreeBSD, Inc.
|
|
|
|
Topic: Coredumps and symbolic links
|
|
|
|
Category: core
|
|
Module: kernel
|
|
Announced: 1999-09-15
|
|
Affects: FreeBSD 3.2 (and earlier)
|
|
FreeBSD-current before the correction date.
|
|
FreeBSD 3.2-stable before the correction date.
|
|
FreeBSD 2.2.8-stable before the correction date.
|
|
Corrected: FreeBSD-3.3 RELEASE
|
|
FreeBSD-current as of 1999/08/26
|
|
FreeBSD-3.2-stable as of 1999/08/26
|
|
FreeBSD-2.2.8-stable as of 1999/08/29
|
|
The FreeBSD-3.3-RC series of releases are not affected.
|
|
FreeBSD only: NO
|
|
|
|
Patches: ftp://ftp.freebsd.org/pub/FreeBSD/CERT/patches/SA-99:04/
|
|
|
|
I. Background
|
|
|
|
As a diagnostic aid to help programmers find bugs in their programs,
|
|
the system creates core files when an illegal instruction or other
|
|
fatal error happens. A flaw in the kernel allowed it to follow
|
|
symbolic links when creating core files.
|
|
|
|
II. Problem Description
|
|
|
|
The fts library functions had a flaw in them where which would lead to
|
|
a core dump when periodic ran the security checking scripts (or other
|
|
scripts which traverse trees that can be controlled by users).
|
|
periodic(3) should limit core size to zero to disable core dumps while
|
|
it is executing commands, but does not do so. In addition, the kernel
|
|
should not follow symbolic links.
|
|
|
|
All three of these problems caused a situation where it was possible
|
|
for an attacker could create or overwrite an arbitrary file on the
|
|
system with a moderate degree of controll of its contents to cause a
|
|
problem.
|
|
|
|
III. Impact
|
|
|
|
Local users could gain root access.
|
|
|
|
IV. Workaround
|
|
|
|
One can workaround this problem by preventing core dumps for periodic.
|
|
This solution is less than completely satisfying, since it only plugs
|
|
the known exploit hole. None the less, this may provide a short term
|
|
stopgap solution until a new kernel and/or userland can be installed.
|
|
|
|
# mv /usr/sbin/periodic /usr/sbin/periodic.bin
|
|
# cat > /usr/sbin/periodic
|
|
#!/bin/sh
|
|
ulimit -c 0
|
|
/usr/sbin/periodic.bin $*
|
|
^D
|
|
# chmod 555 /usr/sbin/periodic
|
|
|
|
Another alternative would be to update the fts routines to a version
|
|
newer than 1999/09/02 (for -current or 3.3-stable) or 1999/09/04 (for
|
|
2.2.8-stable). However, this requires that you rebuild via "make
|
|
world" to take effect.
|
|
|
|
V. Solution
|
|
|
|
Please note: there is a separate advisory describing the fts problem
|
|
and solution. Please see FreeBSD-SA-99:05.fts.asc in the advisories
|
|
directory for additional information about the fts patch.
|
|
|
|
Apply the following patches to your kernel. They will disallow
|
|
following symbolic links when creating core files. This will stop
|
|
this attack, and all similar such attacks.
|
|
|
|
Here's the patch for freebsd-current:
|
|
|
|
*** kern/imgact_elf.c 1999/07/09 19:10:14 1.61
|
|
--- kern/imgact_elf.c 1999/08/26 17:32:48 1.62
|
|
***************
|
|
*** 722,729 ****
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
|
|
! NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
--- 722,729 ----
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
|
|
! NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
*** kern/imgact_aout.c 1999/05/17 00:53:36 1.52
|
|
--- kern/imgact_aout.c 1999/08/26 17:32:48 1.53
|
|
***************
|
|
*** 264,271 ****
|
|
name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
! NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
--- 264,271 ----
|
|
name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
! NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
|
|
Here's the patch for freebsd-3.2-stable:
|
|
|
|
*** kern/imgact_elf.c 1999/07/15 13:01:54 1.44.2.4
|
|
--- kern/imgact_elf.c 1999/08/26 17:35:03 1.44.2.5
|
|
***************
|
|
*** 699,706 ****
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
|
|
! NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
--- 699,706 ----
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
|
|
! NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
*** kern/imgact_aout.c 1999/04/14 04:55:22 1.44.2.1
|
|
--- kern/imgact_aout.c 1999/08/26 17:35:02 1.44.2.2
|
|
***************
|
|
*** 259,266 ****
|
|
name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
! NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
--- 259,266 ----
|
|
name = expand_name(p->p_comm, p->p_ucred->cr_uid, p->p_pid);
|
|
if (name == NULL)
|
|
return (EFAULT); /* XXX -- not the best error */
|
|
! NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
|
|
! error = vn_open(&nd, O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR);
|
|
free(name, M_TEMP);
|
|
if (error)
|
|
return (error);
|
|
|
|
Here's the patch for FreeBSD-2.2.8-stable
|
|
|
|
*** sys/LINK/fcntl.h Wed Dec 18 05:08:08 1996
|
|
--- sys/fcntl.h Fri Aug 27 14:39:26 1999
|
|
***************
|
|
*** 84,89 ****
|
|
--- 84,90 ----
|
|
#define O_EXLOCK 0x0020 /* open with exclusive file lock */
|
|
#define O_ASYNC 0x0040 /* signal pgrp when data ready */
|
|
#define O_FSYNC 0x0080 /* synchronous writes */
|
|
+ #define O_NOFOLLOW 0x0100 /* don't follow symlinks */
|
|
#endif
|
|
#define O_CREAT 0x0200 /* create if nonexistent */
|
|
#define O_TRUNC 0x0400 /* truncate to zero length */
|
|
*** kern/LINK/kern_sig.c Sat Dec 21 10:57:24 1996
|
|
--- kern/kern_sig.c Fri Aug 27 14:38:25 1999
|
|
***************
|
|
*** 1241,1249 ****
|
|
p->p_rlimit[RLIMIT_CORE].rlim_cur)
|
|
return (EFAULT);
|
|
sprintf(name, "%s.core", p->p_comm);
|
|
! NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, name, p);
|
|
if ((error = vn_open(&nd,
|
|
! O_CREAT | FWRITE, S_IRUSR | S_IWUSR)))
|
|
return (error);
|
|
vp = nd.ni_vp;
|
|
|
|
--- 1241,1249 ----
|
|
p->p_rlimit[RLIMIT_CORE].rlim_cur)
|
|
return (EFAULT);
|
|
sprintf(name, "%s.core", p->p_comm);
|
|
! NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, p);
|
|
if ((error = vn_open(&nd,
|
|
! O_CREAT | FWRITE | O_NOFOLLOW, S_IRUSR | S_IWUSR)))
|
|
return (error);
|
|
vp = nd.ni_vp;
|
|
|
|
*** kern/LINK/vfs_vnops.c Sat Mar 8 07:16:18 1997
|
|
--- kern/vfs_vnops.c Fri Aug 27 14:37:01 1999
|
|
***************
|
|
*** 87,93 ****
|
|
if (fmode & O_CREAT) {
|
|
ndp->ni_cnd.cn_nameiop = CREATE;
|
|
ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
|
|
! if ((fmode & O_EXCL) == 0)
|
|
ndp->ni_cnd.cn_flags |= FOLLOW;
|
|
error = namei(ndp);
|
|
if (error)
|
|
--- 87,93 ----
|
|
if (fmode & O_CREAT) {
|
|
ndp->ni_cnd.cn_nameiop = CREATE;
|
|
ndp->ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
|
|
! if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0)
|
|
ndp->ni_cnd.cn_flags |= FOLLOW;
|
|
error = namei(ndp);
|
|
if (error)
|
|
***************
|
|
*** 119,125 ****
|
|
}
|
|
} else {
|
|
ndp->ni_cnd.cn_nameiop = LOOKUP;
|
|
! ndp->ni_cnd.cn_flags = FOLLOW | LOCKLEAF;
|
|
error = namei(ndp);
|
|
if (error)
|
|
return (error);
|
|
--- 119,126 ----
|
|
}
|
|
} else {
|
|
ndp->ni_cnd.cn_nameiop = LOOKUP;
|
|
! ndp->ni_cnd.cn_flags =
|
|
! ((fmode & O_NOFOLLOW) ? NOFOLLOW : FOLLOW) | LOCKLEAF;
|
|
error = namei(ndp);
|
|
if (error)
|
|
return (error);
|
|
*** kern/LINK/vfs_syscalls.c Wed Aug 4 12:44:30 1999
|
|
--- kern/vfs_syscalls.c Sat Aug 28 10:48:51 1999
|
|
***************
|
|
*** 694,699 ****
|
|
--- 694,701 ----
|
|
flags = FFLAGS(uap->flags);
|
|
if ((flags & FREAD + FWRITE) == 0)
|
|
return (EINVAL);
|
|
+ if (flags & O_NOFOLLOW)
|
|
+ flags &= ~O_NOFOLLOW;
|
|
error = falloc(p, &nfp, &indx);
|
|
if (error)
|
|
return (error);
|
|
|
|
|
|
=============================================================================
|
|
FreeBSD, Inc.
|
|
|
|
Web Site: http://www.freebsd.org/
|
|
Confidential contacts: security-officer@freebsd.org
|
|
Security notifications: security-notifications@freebsd.org
|
|
Security public discussion: freebsd-security@freebsd.org
|
|
PGP Key: ftp://ftp.freebsd.org/pub/FreeBSD/CERT/public_key.asc
|
|
|
|
Notice: Any patches in this document may not apply cleanly due to
|
|
modifications caused by digital signature or mailer software.
|
|
Please reference the URL listed at the top of this document
|
|
for original copies of all patches if necessary.
|
|
=============================================================================
|
|
|
|
-----BEGIN PGP SIGNATURE-----
|
|
Version: 2.6.3ia
|
|
Charset: noconv
|
|
Comment: Processed by Mailcrypt 3.4, an Emacs/PGP interface
|
|
|
|
iQCVAwUBN+B44VUuHi5z0oilAQHkwwP9HeLkRJY/iXIYXUx8/A38EAxM/TAqxoiI
|
|
ym7ZyktNtuCbum8ovCIfmkpnafaFyXmVSDhCX77LbIy+1clEBnelyueJ9TbKpBgU
|
|
KWjTWmfj/7QsU2Ya/f7FK80ee8y7GjTTYxilnxxzTmM8ihHzFXrPHudoO4lTR7Op
|
|
2VII3pQVxOM=
|
|
=bJXX
|
|
-----END PGP SIGNATURE-----
|