git: 015991cb9715 - releng/13.1 - Clear non-x86 compat stat syscall kernel stack memory disclosure

From: Ed Maste <emaste_at_FreeBSD.org>
Date: Wed, 30 Mar 2022 03:09:32 UTC
The branch releng/13.1 has been updated by emaste:

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

commit 015991cb9715c4af620e11d3aa5da20eff7eac5d
Author:     Ed Maste <emaste@FreeBSD.org>
AuthorDate: 2022-03-29 17:55:21 +0000
Commit:     Ed Maste <emaste@FreeBSD.org>
CommitDate: 2022-03-30 01:25:34 +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
    
    (cherry picked from commit f90cd1ae30b5f49e9f6ea58a0628ce1c8d8822bc)
    (cherry picked from commit ccd701d27a747ea7266f434170169072e8686f30)
    
    Approved by:    re (gjb)
---
 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 e56ab423f538..4ef33774d6bb 100644
--- a/sys/compat/freebsd32/freebsd32_misc.c
+++ b/sys/compat/freebsd32/freebsd32_misc.c
@@ -2135,6 +2135,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);
@@ -2296,6 +2307,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) {