On Wed, May 27, 2020 at 07:26:30PM -0700, Yonghong Song wrote: >> --- a/kernel/trace/bpf_trace.c~xxx >> +++ a/kernel/trace/bpf_trace.c >> @@ -588,15 +588,22 @@ BPF_CALL_5(bpf_seq_printf, struct seq_fi >> } >> if (fmt[i] == 's') { >> + void *unsafe_ptr; >> + >> /* try our best to copy */ >> if (memcpy_cnt >= MAX_SEQ_PRINTF_MAX_MEMCPY) { >> err = -E2BIG; >> goto out; >> } >> - err = strncpy_from_unsafe(bufs->buf[memcpy_cnt], >> - (void *) (long) args[fmt_cnt], >> - MAX_SEQ_PRINTF_STR_LEN); >> + unsafe_ptr = (void *)(long)args[fmt_cnt]; >> + if ((unsigned long)unsafe_ptr < TASK_SIZE) { >> + err = strncpy_from_user_nofault( >> + bufs->buf[memcpy_cnt], unsafe_ptr, >> + MAX_SEQ_PRINTF_STR_LEN); >> + } else { >> + err = -EFAULT; >> + } > > This probably not right. > The pointer stored at args[fmt_cnt] is a kernel pointer, > but it could be an invalid address and we do not want to fault. > Not sure whether it exists or not, we should use > strncpy_from_kernel_nofault()? If you know it is a kernel pointer with this series it should be strncpy_from_kernel_nofault. But even before the series it should have been strncpy_from_unsafe_strict.