diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 2019-05-04 17:57:47 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 2019-05-04 17:57:47 +0000 |
commit | d794b5345bf3da49645662bc7cedb4813216364c (patch) | |
tree | 00098a9100cba661f5a98429613d9b32c3a9f6c4 /sys/ufs | |
parent | d4a51209cd8cfdc755423b873d2eef5a82c82683 (diff) |
3 bytes of kernel stack address space were leaked into on-disk directories.
With some gritty work up to 254 bytes can be discovered. More details at
https://svnweb.freebsd.org/changeset/base/347066
The impact on OpenBSD is very limited:
1 - such stack bytes can be found in raw-device reads, from group operator.
If you can read the raw disks you can undertake other more powerful actions.
2 - read(2) upon directory fd was disabled July 1997 because I didn't like
how grep * would display garbage and mess up the tty, and applying vis(3)
for just directory reads seemed silly. read(2) was changed to return
0 (EOF). Sep 2016 this was further changed to EISDIR, so you still cannot
see the bad bytes.
3 - In 2013 when guenther adapted the getdents(2) directory-reading system
call to 64-bit ino_t, the userland data format changed to 8-byte-alignment,
making it incompatible with the 4-byte-alignment UFS on-disk format. As
a result of code refactoring the bad bytes were not copied to userland.
Bad bytes will remain in old directories on old filesystems, but nothing makes
those bytes user visible. There will be no errata or syspatch issued. I
urge other systems which do expose the information to userland to issue
errata quickly, since this is a 254 byte infoleak of the stack which is great
for ROP-chain building to attack some other bug. Especially if the kernel
has no layout/link-order randomization ...
ok kettenis jca millert otto ...
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ufs/ufs_lookup.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/sys/ufs/ufs/ufs_lookup.c b/sys/ufs/ufs/ufs_lookup.c index 3825de24188..aeb60636b92 100644 --- a/sys/ufs/ufs/ufs_lookup.c +++ b/sys/ufs/ufs/ufs_lookup.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ufs_lookup.c,v 1.54 2018/12/23 10:46:51 natano Exp $ */ +/* $OpenBSD: ufs_lookup.c,v 1.55 2019/05/04 17:57:46 deraadt Exp $ */ /* $NetBSD: ufs_lookup.c,v 1.7 1996/02/09 22:36:06 christos Exp $ */ /* @@ -671,7 +671,9 @@ ufs_makedirentry(struct inode *ip, struct componentname *cnp, #endif newdirp->d_ino = ip->i_number; newdirp->d_namlen = cnp->cn_namelen; - memcpy(newdirp->d_name, cnp->cn_nameptr, cnp->cn_namelen + 1); + memset(newdirp->d_name + (cnp->cn_namelen & ~(DIR_ROUNDUP-1)), + 0, DIR_ROUNDUP); + memcpy(newdirp->d_name, cnp->cn_nameptr, cnp->cn_namelen); if (OFSFMT(ip)) { newdirp->d_type = 0; # if (BYTE_ORDER == LITTLE_ENDIAN) |