On Thu, 14 May 2020 00:36:28 +0200 Daniel Borkmann <daniel@xxxxxxxxxxxxx> wrote: > On 5/13/20 9:28 PM, Christoph Hellwig wrote: > > On Wed, May 13, 2020 at 12:11:27PM -0700, Linus Torvalds wrote: > >> On Wed, May 13, 2020 at 9:01 AM Christoph Hellwig <hch@xxxxxx> wrote: > >>> > >>> +static void bpf_strncpy(char *buf, long unsafe_addr) > >>> +{ > >>> + buf[0] = 0; > >>> + if (strncpy_from_kernel_nofault(buf, (void *)unsafe_addr, > >>> + BPF_STRNCPY_LEN)) > >>> + strncpy_from_user_nofault(buf, (void __user *)unsafe_addr, > >>> + BPF_STRNCPY_LEN); > >>> +} > >> > >> This seems buggy when I look at it. > >> > >> It seems to think that strncpy_from_kernel_nofault() returns an error code. > >> > >> Not so, unless I missed where you changed the rules. > > > > I didn't change the rules, so yes, this is wrong. > > > >> Also, I do wonder if we shouldn't gate this on TASK_SIZE, and do the > >> user trial first. On architectures where this thing is valid in the > >> first place (ie kernel and user addresses are separate), the test for > >> address size would allow us to avoid a pointless fault due to an > >> invalid kernel access to user space. > >> > >> So I think this function should look something like > >> > >> static void bpf_strncpy(char *buf, long unsafe_addr) > >> { > >> /* Try user address */ > >> if (unsafe_addr < TASK_SIZE) { > >> void __user *ptr = (void __user *)unsafe_addr; > >> if (strncpy_from_user_nofault(buf, ptr, BPF_STRNCPY_LEN) >= 0) > >> return; > >> } > >> > >> /* .. fall back on trying kernel access */ > >> buf[0] = 0; > >> strncpy_from_kernel_nofault(buf, (void *)unsafe_addr, > >> BPF_STRNCPY_LEN); > >> } > >> > >> or similar. No? > > > > So on say s390 TASK_SIZE_USUALLy is (-PAGE_SIZE), which means we'd alway > > try the user copy first, which seems odd. > > > > I'd really like to here from the bpf folks what the expected use case > > is here, and if the typical argument is kernel or user memory. > > It's used for both. Given this is enabled on pretty much all program types, my > assumption would be that usage is still more often on kernel memory than user one. For trace_kprobe.c current order (kernel -> user fallback) is preferred because it has another function dedicated for user memory. Thank you, -- Masami Hiramatsu <mhiramat@xxxxxxxxxx>