diff options
| author | Priya Bala Govindasamy <pgovind2@uci.edu> | 2026-09-23 20:31:45 +0000 |
|---|---|---|
| committer | Petr Pavlu <petr.pavlu@suse.com> | 2026-10-14 10:42:40 +0200 |
| commit | 2e8bac09ed6d7aa2ad4e8a9a6cba67e5835865c2 (patch) | |
| tree | 666f6ba02c163e1444c200560bdea2a73be338d5 /rust | |
| parent | ff7360c5c731356a59171eef732a26a72381a8ba (diff) | |
| download | linux-next-2e8bac09ed6d7aa2ad4e8a9a6cba67e5835865c2.tar.gz linux-next-2e8bac09ed6d7aa2ad4e8a9a6cba67e5835865c2.zip | |
rust: module_param: Fix potentially incorrect access of `SetOnce<T>`
The `set_param` function casts `kernel_param.arg` to `*const SetOnce<T>`
But the Rust module macro in rust/macros/module.rs initializes `arg` with
`#param_name.as_void_ptr()`, and `#param_name` is a `ModuleParamAccess<T>`,
not a `SetOnce<T>`.
ModuleParamAccess<T> has default Rust layout but `set_param` accesses its
first field SetOnce<T> assuming it to be at offset 0. This is not
guaranteed by Rust and could cause type confusion leading to data
corruption.
Fix this by casting `kernel_param.arg` to `ModuleParamAccess<T>` and
then accessing the `value: SetOnce<T>` field.
Fixes: 0b08fc292842 ("rust: introduce module_param module")
Cc: stable@vger.kernel.org
Reported-by: Dylan Zueck <dzueck@uci.edu>
Assisted-by: LLM
Suggested-by: Andreas Hindborg <a.hindborg@kernel.org>
Signed-off-by: Priya Bala Govindasamy <pgovind2@uci.edu>
Signed-off-by: Petr Pavlu <petr.pavlu@suse.com>
Diffstat (limited to 'rust')
| -rw-r--r-- | rust/kernel/module_param.rs | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/rust/kernel/module_param.rs b/rust/kernel/module_param.rs index f9a14765a926..1a2fcbf4a5b3 100644 --- a/rust/kernel/module_param.rs +++ b/rust/kernel/module_param.rs @@ -74,8 +74,13 @@ where crate::error::from_result(|| { let new_value = T::try_from_param_arg(arg)?; - // SAFETY: By function safety requirements, this access is safe. - let container = unsafe { &*((*param).__bindgen_anon_1.arg.cast::<SetOnce<T>>()) }; + // SAFETY: By function safety requirements, `param` is valid for read. + let arg = unsafe { (*param).__bindgen_anon_1.arg }; + let param_access_ptr = arg.cast::<ModuleParamAccess<T>>(); + // SAFETY: The `arg` field is initialized with a pointer to a `static ModuleAccessParam` by + // the rust module macro. Thus, the pointer is valid for use as a reference. + let param_access = unsafe { &*(param_access_ptr) }; + let container = ¶m_access.value; container .populate(new_value) |
