On 5/27/20 9:39 PM, Christoph Hellwig wrote:
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.

The use of strncpy_from_unsafe() mimics old bpf_trace_printk() implementation which just changed to _strict version:
https://lkml.org/lkml/2020/5/18/1309

Agreed that we should change to strncpy_from_unsafe_strict().
I can submit a patch for this.

Thanks!

Reply via email to