Re: kernel/trace/trace_events_synth.c:436:68: sparse: sparse: incorrect type in argument 2 (different address spaces)

From: Steven Rostedt
Date: Wed Oct 19 2022 - 09:51:25 EST


On Wed, 19 Oct 2022 11:43:54 +0800
kernel test robot <lkp@xxxxxxxxx> wrote:

> sparse warnings: (new ones prefixed by >>)
> >> kernel/trace/trace_events_synth.c:436:68: sparse: sparse: incorrect type in argument 2 (different address spaces) @@ expected void const [noderef] __user *unsafe_addr @@ got char *str_val @@
> kernel/trace/trace_events_synth.c:436:68: sparse: expected void const [noderef] __user *unsafe_addr
> kernel/trace/trace_events_synth.c:436:68: sparse: got char *str_val
>
> vim +436 kernel/trace/trace_events_synth.c
>
> 404
> 405 static unsigned int trace_string(struct synth_trace_event *entry,
> 406 struct synth_event *event,
> 407 char *str_val,
> 408 bool is_dynamic,
> 409 unsigned int data_size,
> 410 unsigned int *n_u64)
> 411 {
> 412 unsigned int len = 0;
> 413 char *str_field;
> 414 int ret;
> 415
> 416 if (is_dynamic) {
> 417 u32 data_offset;
> 418
> 419 data_offset = offsetof(typeof(*entry), fields);
> 420 data_offset += event->n_u64 * sizeof(u64);
> 421 data_offset += data_size;
> 422
> 423 len = kern_fetch_store_strlen((unsigned long)str_val);
> 424
> 425 data_offset |= len << 16;
> 426 *(u32 *)&entry->fields[*n_u64] = data_offset;
> 427
> 428 ret = kern_fetch_store_string((unsigned long)str_val, &entry->fields[*n_u64], entry);
> 429
> 430 (*n_u64)++;
> 431 } else {
> 432 str_field = (char *)&entry->fields[*n_u64];
> 433
> 434 #ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
> 435 if ((unsigned long)str_val < TASK_SIZE)
> > 436 ret = strncpy_from_user_nofault(str_field, str_val, STR_VAR_LEN_MAX);
> 437 else
> 438 #endif
> 439 ret = strncpy_from_kernel_nofault(str_field, str_val, STR_VAR_LEN_MAX);
> 440


Does this fix it?

-- Steve

diff --git a/kernel/trace/trace_events_synth.c b/kernel/trace/trace_events_synth.c
index e310052dc83c..2562d7522999 100644
--- a/kernel/trace/trace_events_synth.c
+++ b/kernel/trace/trace_events_synth.c
@@ -433,7 +433,8 @@ static unsigned int trace_string(struct synth_trace_event *entry,

#ifdef CONFIG_ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
if ((unsigned long)str_val < TASK_SIZE)
- ret = strncpy_from_user_nofault(str_field, str_val, STR_VAR_LEN_MAX);
+ ret = strncpy_from_user_nofault(str_field,
+ (__force const void __user *)str_val, STR_VAR_LEN_MAX);
else
#endif
ret = strncpy_from_kernel_nofault(str_field, str_val, STR_VAR_LEN_MAX);