summaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorTheo de Raadt <deraadt@cvs.openbsd.org>2019-05-04 17:57:47 +0000
committerTheo de Raadt <deraadt@cvs.openbsd.org>2019-05-04 17:57:47 +0000
commitd794b5345bf3da49645662bc7cedb4813216364c (patch)
tree00098a9100cba661f5a98429613d9b32c3a9f6c4 /sys/ufs
parentd4a51209cd8cfdc755423b873d2eef5a82c82683 (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.c6
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)