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
This commit is contained in:
Ed Maste 2022-03-29 13:55:21 -04:00
parent e123e2294c
commit f90cd1ae30

View file

@ -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) {