Hi, I'm the author of that bug report. I believe you are mistaken: I do not think that this is a documentation issue. I strongly believe that the documentation is correct and the function behavior itself is wrong. bpf_probe_read_kernel_str() behaves like it should (as documented). bpf_probe_read_user_str() has the same documentation as the above (so should have the same behavior), yet it behaves differently. I see no reason why these two functions should return different (non-error) values for the same string. I can try to prepare a code patch for this issue, but I haven't done this previously so this is all a bit new to me. Kind regards, Max -----Original Message----- From: Alexei Starovoitov <alexei.starovoitov@xxxxxxxxx> Sent: Sunday, July 23, 2023 4:02 AM To: Bagas Sanjaya <bagasdotme@xxxxxxxxx> Cc: Ingo Molnar <mingo@xxxxxxxxxx>; Masami Hiramatsu <mhiramat@xxxxxxxxxx>; Steven Rostedt (Google) <rostedt@xxxxxxxxxxx>; Fröhling, Maximilian <Maximilian.Froehling@xxxxxxxx>; Linux Kernel Mailing List <linux-kernel@xxxxxxxxxxxxxxx>; Linux BPF <bpf@xxxxxxxxxxxxxxx>; Linux Memory Management List <linux-mm@xxxxxxxxx> Subject: Re: bpf: bpf_probe_read_user_str() returns 0 for empty strings On Sat, Jul 22, 2023 at 6:53 PM Bagas Sanjaya <bagasdotme@xxxxxxxxx> wrote: > > Hi, > > I notice a bug report on Bugzilla [1]. Quoting from it: > > > Overview: > > > > From within eBPF, calling the helper function bpf_probe_read_user_str(void *dst, __u32 size, const void *unsafe_ptr returns 0 when the source string (void *unsafe_ptr) consists of a string containing only a single null-byte. > > > > This violates various functions documentations (the helper and various internal kernel functions), which all state: Sounds like the bugzilla author believes it's a documentation issue. If so, please encourage the author to send the patch to fix the doc. > > > >> On success, the strictly positive length of the output string, > >> including the trailing NUL character. On error, a negative value. > > > > To me, this states that the function should return 1 for char myString[] = ""; However, this is not the case. The function returns 0 instead. > > > > For non-empty strings, it works as expected. For example, char myString[] = "abc"; returns 4. > > > > Steps to Reproduce: > > * Write an eBPF program that calls bpf_probe_read_user_str(), using a userspace pointer pointing to an empty string. > > * Store the result value of that function > > * Do the same thing, but try out bpf_probe_read_kernel_str(), like this: > > char empty[] = ""; > > char copy[5]; > > long ret = bpf_probe_read_kernel_str(copy, 5, empty); > > * Compare the return value of bpf_probe_read_user_str() and > > bpf_probe_read_kernel_str() > > > > Expected Result: > > > > Both functions return 1 (because of the single NULL byte). > > > > Actual Result: > > > > bpf_probe_read_user_str() returns 0, while bpf_probe_read_kernel_str() returns 1. > > > > Additional Information: > > > > I believe I can see the bug on the current Linux kernel master branch. > > > > In the file/function mm/maccess.c::strncpy_from_user_nofault() the helper implementation calls strncpy_from_user(), which returns the length without trailing 0. Hence this function returns 0 for an empty string. > > > > However, in line 192 (as of commit fdf0eaf11452d72945af31804e2a1048ee1b574c) there is a check that only increments ret, if it is > 0. This appears to be the logic that adds the trailing null byte. Since the check only does this for a ret > 0, a ret of 0 remains at 0. > > > > This is a possible off-by-one error that might cause the behavior. > > See Bugzilla for the full thread. > > FYI, the culprit line is introduced by commit 3d7081822f7f9e > ("uaccess: Add non-pagefault user-space read functions"). I Cc: > culprit SoB so that they can look into this bug. > > Thanks. > > [1]: https://bugzilla.kernel.org/show_bug.cgi?id=217679 > > -- > An old man doll... just what I always wanted! - Clara >