git: f90cd1ae30b5 - main - Clear non-x86 compat stat syscall kernel stack memory disclosure

From: Ed Maste <emaste_at_FreeBSD.org>
Date: Tue, 29 Mar 2022 20:14:45 UTC
The branch main has been updated by emaste:

URL: https://cgit.FreeBSD.org/src/commit/?id=f90cd1ae30b5f49e9f6ea58a0628ce1c8d8822bc

commit f90cd1ae30b5f49e9f6ea58a0628ce1c8d8822bc
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2022-03-29 17:55:21 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2022-03-29 20:10:04 +0000

    Clear non-x86 compat stat syscall kernel stack memory disclosure
    
    32-bit architectures other than i386 have 64-bit time_t which results
    in a struct timespec with 12 bytes for tv_sec and tv_nsec, and 4 bytes
    of padding.  Zero the padding holes in struct stat32 and struct
    freebsd11_stat32.
    
    i386 has 32-bit time_t; struct timespec is 8 bytes and has no padding.
    
    Found by inspection, prompted by a report by Reno Robert of Trend Micro
    Zero Day Initiative.  The originally reported issue (ZDI-CAN-14538) is
    already fixed in all supported FreeBSD versions (it was addressed
    incidentally as part of the 64-bit inode project).
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D34709
---
 sys/compat/freebsd32/freebsd32_misc.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/sys/compat/freebsd32/freebsd32_misc.c b/sys/compat/freebsd32/freebsd32_misc.c
index 01337ea51c50..2b20170bfd2f 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2176,6 +2176,17 @@ static void
 copy_stat(struct stat *in, struct stat32 *out)
 {
 
+#ifndef __amd64__
+	/*
+	 * 32-bit architectures other than i386 have 64-bit time_t.  This
+	 * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
+	 * and 4 bytes of padding.  Zero the padding holes in struct stat32.
+	 */
+	bzero(&out->st_atim, sizeof(out->st_atim));
+	bzero(&out->st_mtim, sizeof(out->st_mtim));
+	bzero(&out->st_ctim, sizeof(out->st_ctim));
+	bzero(&out->st_birthtim, sizeof(out->st_birthtim));
+#endif
 	CP(*in, *out, st_dev);
 	CP(*in, *out, st_ino);
 	CP(*in, *out, st_mode);
@@ -2337,6 +2348,18 @@ static int
 freebsd11_cvtstat32(struct stat *in, struct freebsd11_stat32 *out)
 {
 
+#ifndef __amd64__
+	/*
+	 * 32-bit architectures other than i386 have 64-bit time_t.  This
+	 * results in struct timespec32 with 12 bytes for tv_sec and tv_nsec,
+	 * and 4 bytes of padding.  Zero the padding holes in freebsd11_stat32.
+	 */
+	bzero(&out->st_atim, sizeof(out->st_atim));
+	bzero(&out->st_mtim, sizeof(out->st_mtim));
+	bzero(&out->st_ctim, sizeof(out->st_ctim));
+	bzero(&out->st_birthtim, sizeof(out->st_birthtim));
+#endif
+
 	CP(*in, *out, st_ino);
 	if (in->st_ino != out->st_ino) {
 		switch (ino64_trunc_error) {