Sun May 5 01:48:53 2019 UTC ()
Zero out all the dirent padding not just one byte, to avoid kernel memory
disclosure (from https://svnweb.freebsd.org/base?view=revision&revision=347066)


(christos)
diff -r1.25 -r1.26 src/sys/ufs/ufs/dir.h
diff -r1.148 -r1.149 src/sys/ufs/ufs/ufs_lookup.c

cvs diff -r1.25 -r1.26 src/sys/ufs/ufs/dir.h (expand / switch to unified diff)

--- src/sys/ufs/ufs/dir.h 2015/09/01 06:16:03 1.25
+++ src/sys/ufs/ufs/dir.h 2019/05/05 01:48:53 1.26
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: dir.h,v 1.25 2015/09/01 06:16:03 dholland Exp $ */ 1/* $NetBSD: dir.h,v 1.26 2019/05/05 01:48:53 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1982, 1986, 1989, 1993 4 * Copyright (c) 1982, 1986, 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc. 6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed 7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph 8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc. 10 * the permission of UNIX System Laboratories, Inc.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -101,28 +101,31 @@ struct direct { @@ -101,28 +101,31 @@ struct direct {
101 101
102/* 102/*
103 * Convert between stat structure types and directory types. 103 * Convert between stat structure types and directory types.
104 */ 104 */
105#define IFTODT(mode) (((mode) & 0170000) >> 12) 105#define IFTODT(mode) (((mode) & 0170000) >> 12)
106#define DTTOIF(dirtype) ((dirtype) << 12) 106#define DTTOIF(dirtype) ((dirtype) << 12)
107 107
108/* 108/*
109 * The UFS_DIRSIZ macro gives the minimum record length which will hold 109 * The UFS_DIRSIZ macro gives the minimum record length which will hold
110 * the directory entry. This requires the amount of space in struct direct 110 * the directory entry. This requires the amount of space in struct direct
111 * without the d_name field, plus enough space for the name with a terminating 111 * without the d_name field, plus enough space for the name with a terminating
112 * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary. 112 * null byte (dp->d_namlen+1), rounded up to a 4 byte boundary.
113 */ 113 */
 114#define DIR_ROUNDUP 4
 115#define UFS_NAMEROUNDUP(namlen) (((namlen) + DIR_ROUNDUP) & ~(DIR_ROUNDUP - 1))
 116#define UFS_NAMEPAD(namlen) (DIR_ROUNDUP - ((namlen) & (DIR_ROUNDUP - 1)))
114#define UFS_DIRECTSIZ(namlen) \ 117#define UFS_DIRECTSIZ(namlen) \
115 ((sizeof(struct direct) - (FFS_MAXNAMLEN+1)) + (((namlen)+1 + 3) &~ 3)) 118 ((sizeof(struct direct) - (FFS_MAXNAMLEN+1)) + UFS_NAMEROUNDUP(namlen))
116 119
117#if (BYTE_ORDER == LITTLE_ENDIAN) 120#if (BYTE_ORDER == LITTLE_ENDIAN)
118#define UFS_DIRSIZ(oldfmt, dp, needswap) \ 121#define UFS_DIRSIZ(oldfmt, dp, needswap) \
119 (((oldfmt) && !(needswap)) ? \ 122 (((oldfmt) && !(needswap)) ? \
120 UFS_DIRECTSIZ((dp)->d_type) : UFS_DIRECTSIZ((dp)->d_namlen)) 123 UFS_DIRECTSIZ((dp)->d_type) : UFS_DIRECTSIZ((dp)->d_namlen))
121#else 124#else
122#define UFS_DIRSIZ(oldfmt, dp, needswap) \ 125#define UFS_DIRSIZ(oldfmt, dp, needswap) \
123 (((oldfmt) && (needswap)) ? \ 126 (((oldfmt) && (needswap)) ? \
124 UFS_DIRECTSIZ((dp)->d_type) : UFS_DIRECTSIZ((dp)->d_namlen)) 127 UFS_DIRECTSIZ((dp)->d_type) : UFS_DIRECTSIZ((dp)->d_namlen))
125#endif 128#endif
126 129
127/* 130/*
128 * UFS_OLDDIRFMT and UFS_NEWDIRFMT are code numbers for a directory 131 * UFS_OLDDIRFMT and UFS_NEWDIRFMT are code numbers for a directory

cvs diff -r1.148 -r1.149 src/sys/ufs/ufs/ufs_lookup.c (expand / switch to unified diff)

--- src/sys/ufs/ufs/ufs_lookup.c 2017/10/27 12:25:15 1.148
+++ src/sys/ufs/ufs/ufs_lookup.c 2019/05/05 01:48:53 1.149
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ufs_lookup.c,v 1.148 2017/10/27 12:25:15 joerg Exp $ */ 1/* $NetBSD: ufs_lookup.c,v 1.149 2019/05/05 01:48:53 christos Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc. 6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed 7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph 8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc. 10 * the permission of UNIX System Laboratories, Inc.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE. 34 * SUCH DAMAGE.
35 * 35 *
36 * @(#)ufs_lookup.c 8.9 (Berkeley) 8/11/94 36 * @(#)ufs_lookup.c 8.9 (Berkeley) 8/11/94
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.148 2017/10/27 12:25:15 joerg Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.149 2019/05/05 01:48:53 christos Exp $");
41 41
42#ifdef _KERNEL_OPT 42#ifdef _KERNEL_OPT
43#include "opt_ffs.h" 43#include "opt_ffs.h"
44#endif 44#endif
45 45
46#include <sys/param.h> 46#include <sys/param.h>
47#include <sys/systm.h> 47#include <sys/systm.h>
48#include <sys/namei.h> 48#include <sys/namei.h>
49#include <sys/buf.h> 49#include <sys/buf.h>
50#include <sys/file.h> 50#include <sys/file.h>
51#include <sys/stat.h> 51#include <sys/stat.h>
52#include <sys/mount.h> 52#include <sys/mount.h>
53#include <sys/vnode.h> 53#include <sys/vnode.h>
@@ -783,30 +783,35 @@ ufs_dirbadentry(const struct vnode *dp,  @@ -783,30 +783,35 @@ ufs_dirbadentry(const struct vnode *dp,
783 } 783 }
784 return NULL; 784 return NULL;
785} 785}
786 786
787/* 787/*
788 * Construct a new directory entry after a call to namei, using the 788 * Construct a new directory entry after a call to namei, using the
789 * name in the componentname argument cnp. The argument ip is the 789 * name in the componentname argument cnp. The argument ip is the
790 * inode to which the new directory entry will refer. 790 * inode to which the new directory entry will refer.
791 */ 791 */
792void 792void
793ufs_makedirentry(struct inode *ip, struct componentname *cnp, 793ufs_makedirentry(struct inode *ip, struct componentname *cnp,
794 struct direct *newdirp) 794 struct direct *newdirp)
795{ 795{
 796 size_t namelen = cnp->cn_namelen;
 797
796 newdirp->d_ino = ip->i_number; 798 newdirp->d_ino = ip->i_number;
797 newdirp->d_namlen = cnp->cn_namelen; 799 newdirp->d_namlen = namelen;
798 memcpy(newdirp->d_name, cnp->cn_nameptr, (size_t)cnp->cn_namelen); 800 memcpy(newdirp->d_name, cnp->cn_nameptr, namelen);
799 newdirp->d_name[cnp->cn_namelen] = '\0'; 801
 802 /* Zero out padding */
 803 memset(&newdirp->d_name[namelen], 0, UFS_NAMEPAD(namelen));
 804
800 if (FSFMT(ITOV(ip))) 805 if (FSFMT(ITOV(ip)))
801 newdirp->d_type = 0; 806 newdirp->d_type = 0;
802 else 807 else
803 newdirp->d_type = IFTODT(ip->i_mode); 808 newdirp->d_type = IFTODT(ip->i_mode);
804} 809}
805 810
806 811
807static int 812static int
808ufs_dirgrow(struct vnode *dvp, const struct ufs_lookup_results *ulr, 813ufs_dirgrow(struct vnode *dvp, const struct ufs_lookup_results *ulr,
809 struct vnode *tvp, struct direct *dirp, 814 struct vnode *tvp, struct direct *dirp,
810 struct componentname *cnp, struct buf *newdirbp) 815 struct componentname *cnp, struct buf *newdirbp)
811{ 816{
812 const kauth_cred_t cr = cnp->cn_cred; 817 const kauth_cred_t cr = cnp->cn_cred;