diff options
author | Ka Ho Ng <khng@FreeBSD.org> | 2023-07-07 04:21:01 +0000 |
---|---|---|
committer | Ka Ho Ng <khng@FreeBSD.org> | 2023-07-24 02:01:40 +0000 |
commit | 7938d643d2275cf95d5734f5895b7e9d00fcb448 (patch) | |
tree | d72aff7504eb389a5fed114d111a8738f462cb0b | |
parent | 254cdd5b2214112fb78462919433024589b2bcac (diff) | |
download | src-7938d643d2275cf95d5734f5895b7e9d00fcb448.tar.gz src-7938d643d2275cf95d5734f5895b7e9d00fcb448.zip |
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
(cherry picked from commit 034c0856018ccf73c0f2d6140825f3edf43f47b2)
-rw-r--r-- | sys/kern/kern_module.c | 5 |
1 files changed, 2 insertions, 3 deletions
diff --git a/sys/kern/kern_module.c b/sys/kern/kern_module.c index 1798a834dcec..7128525ddb66 100644 --- a/sys/kern/kern_module.c +++ b/sys/kern/kern_module.c @@ -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; |