modules: fix freebsd32_modstat on big endian platforms

The layout of modspecific_t on both little endian and big endian are as
follows:
|0|1|2|3|4|5|6|7|
+-------+-------+
|uintval|       |
+-------+-------+
|ulongval       |
+-------+-------+

For the following code snippet:
        CP(mod->data, data32, longval);
        CP(mod->data, data32, ulongval);
It only takes care of little endian platforms that it truncates the
highest 32bit automatically. However on big endian platforms it takes
the highest 32bit instead. This eventually returns a garbage syscall
number to the 32bit userland.

Since modspecific_t's usage currently is for the use of syscall modules,
we only initialize modspecific32_t with uintval. Now on both BE and LE
64-bit platforms it always pick up the first 4 bytes.

Sponsored by:	Juniper Networks, Inc.
Reviewed by:	markj
Differential Revision:	https://reviews.freebsd.org/D40814
MFC after:	1 week
This commit is contained in:
Ka Ho Ng 2023-07-07 00:21:01 -04:00
parent 97f14168f2
commit 034c085601

View File

@ -520,10 +520,9 @@ freebsd32_modstat(struct thread *td, struct freebsd32_modstat_args *uap)
id = mod->id;
refs = mod->refs;
name = mod->name;
CP(mod->data, data32, intval);
_Static_assert(sizeof(data32) == sizeof(data32.uintval),
"bad modspecific32_t size");
CP(mod->data, data32, uintval);
CP(mod->data, data32, longval);
CP(mod->data, data32, ulongval);
MOD_SUNLOCK;
stat32 = uap->stat;