FreeBSD Security Advisory: FreeBSD-SA-99:04.core
FreeBSD Security Officer
security-officer at freebsd.org
Wed Sep 15 22:26:08 PDT 1999
-----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 at freebsd.org
Security notifications: security-notifications at freebsd.org
Security public discussion: freebsd-security at 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-----
This is the moderated mailing list freebsd-announce.
The list contains announcements of new FreeBSD capabilities,
important events and project milestones.
See also the FreeBSD Web pages at http://www.freebsd.org
To Unsubscribe: send mail to majordomo at FreeBSD.org
with "unsubscribe freebsd-announce" in the body of the message
More information about the freebsd-announce
mailing list