2019-01-18 13:33:03

by Jiri Olsa

[permalink] [raw]
Subject: [PATCH] bpftool: Fix prog dump by tag

Lance reported an issue with bpftool not being able to
dump program if there are more programs loaded and you
want to dump any but the first program, like:

# bpftool prog
28: kprobe name trace_req_start tag 1dfc28ba8b3dd597 gpl
loaded_at 2019-01-18T17:02:40+1100 uid 0
xlated 112B jited 109B memlock 4096B map_ids 13
29: kprobe name trace_req_compl tag 5b6a5ecc6030a683 gpl
loaded_at 2019-01-18T17:02:40+1100 uid 0
xlated 928B jited 575B memlock 4096B map_ids 13,14
# bpftool prog dum jited tag 1dfc28ba8b3dd597
0: push %rbp
1: mov %rsp,%rbp
...

# bpftool prog dum jited tag 5b6a5ecc6030a683
Error: can't get prog info (29): Bad address

The problem is in the prog_fd_by_tag function not cleaning
the struct bpf_prog_info before another request, so the
previous program length is still in there and kernel assumes
it needs to dump the program, which fails because there's no
user pointer set.

Moving the struct bpf_prog_info declaration into the loop,
so it gets cleaned before each query.

Reported-by: Lance Digby <[email protected]>
Signed-off-by: Jiri Olsa <[email protected]>
---
tools/bpf/bpftool/prog.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c
index 2d1bb7d6ff51..b54ed82b9589 100644
--- a/tools/bpf/bpftool/prog.c
+++ b/tools/bpf/bpftool/prog.c
@@ -78,13 +78,14 @@ static void print_boot_time(__u64 nsecs, char *buf, unsigned int size)

static int prog_fd_by_tag(unsigned char *tag)
{
- struct bpf_prog_info info = {};
- __u32 len = sizeof(info);
unsigned int id = 0;
int err;
int fd;

while (true) {
+ struct bpf_prog_info info = {};
+ __u32 len = sizeof(info);
+
err = bpf_prog_get_next_id(id, &id);
if (err) {
p_err("%s", strerror(errno));
--
2.17.2



2019-01-18 19:01:39

by Quentin Monnet

[permalink] [raw]
Subject: Re: [PATCH] bpftool: Fix prog dump by tag

2019-01-18 13:58 UTC+0100 ~ Jiri Olsa <[email protected]>
> Lance reported an issue with bpftool not being able to
> dump program if there are more programs loaded and you
> want to dump any but the first program, like:
>
> # bpftool prog
> 28: kprobe name trace_req_start tag 1dfc28ba8b3dd597 gpl
> loaded_at 2019-01-18T17:02:40+1100 uid 0
> xlated 112B jited 109B memlock 4096B map_ids 13
> 29: kprobe name trace_req_compl tag 5b6a5ecc6030a683 gpl
> loaded_at 2019-01-18T17:02:40+1100 uid 0
> xlated 928B jited 575B memlock 4096B map_ids 13,14
> # bpftool prog dum jited tag 1dfc28ba8b3dd597
> 0: push %rbp
> 1: mov %rsp,%rbp
> ...
>
> # bpftool prog dum jited tag 5b6a5ecc6030a683
> Error: can't get prog info (29): Bad address
>
> The problem is in the prog_fd_by_tag function not cleaning
> the struct bpf_prog_info before another request, so the
> previous program length is still in there and kernel assumes
> it needs to dump the program, which fails because there's no
> user pointer set.
>
> Moving the struct bpf_prog_info declaration into the loop,
> so it gets cleaned before each query.
>
> Reported-by: Lance Digby <[email protected]>
> Signed-off-by: Jiri Olsa <[email protected]>

Thanks for the fix!

Reviewed-by: Quentin Monnet <[email protected]>

2019-01-18 19:32:17

by Jakub Kicinski

[permalink] [raw]
Subject: Re: [PATCH] bpftool: Fix prog dump by tag

On Fri, 18 Jan 2019 13:58:17 +0100, Jiri Olsa wrote:
> Lance reported an issue with bpftool not being able to
> dump program if there are more programs loaded and you
> want to dump any but the first program, like:
>
> # bpftool prog
> 28: kprobe name trace_req_start tag 1dfc28ba8b3dd597 gpl
> loaded_at 2019-01-18T17:02:40+1100 uid 0
> xlated 112B jited 109B memlock 4096B map_ids 13
> 29: kprobe name trace_req_compl tag 5b6a5ecc6030a683 gpl
> loaded_at 2019-01-18T17:02:40+1100 uid 0
> xlated 928B jited 575B memlock 4096B map_ids 13,14
> # bpftool prog dum jited tag 1dfc28ba8b3dd597
> 0: push %rbp
> 1: mov %rsp,%rbp
> ...
>
> # bpftool prog dum jited tag 5b6a5ecc6030a683
> Error: can't get prog info (29): Bad address
>
> The problem is in the prog_fd_by_tag function not cleaning
> the struct bpf_prog_info before another request, so the
> previous program length is still in there and kernel assumes
> it needs to dump the program, which fails because there's no
> user pointer set.
>
> Moving the struct bpf_prog_info declaration into the loop,
> so it gets cleaned before each query.
>
> Reported-by: Lance Digby <[email protected]>
> Signed-off-by: Jiri Olsa <[email protected]>

Aw.

Acked-by: Jakub Kicinski <[email protected]>

Thanks!

2019-01-23 09:00:36

by Daniel Borkmann

[permalink] [raw]
Subject: Re: [PATCH] bpftool: Fix prog dump by tag

On 01/18/2019 01:58 PM, Jiri Olsa wrote:
> Lance reported an issue with bpftool not being able to
> dump program if there are more programs loaded and you
> want to dump any but the first program, like:
>
> # bpftool prog
> 28: kprobe name trace_req_start tag 1dfc28ba8b3dd597 gpl
> loaded_at 2019-01-18T17:02:40+1100 uid 0
> xlated 112B jited 109B memlock 4096B map_ids 13
> 29: kprobe name trace_req_compl tag 5b6a5ecc6030a683 gpl
> loaded_at 2019-01-18T17:02:40+1100 uid 0
> xlated 928B jited 575B memlock 4096B map_ids 13,14
> # bpftool prog dum jited tag 1dfc28ba8b3dd597
> 0: push %rbp
> 1: mov %rsp,%rbp
> ...
>
> # bpftool prog dum jited tag 5b6a5ecc6030a683
> Error: can't get prog info (29): Bad address
>
> The problem is in the prog_fd_by_tag function not cleaning
> the struct bpf_prog_info before another request, so the
> previous program length is still in there and kernel assumes
> it needs to dump the program, which fails because there's no
> user pointer set.
>
> Moving the struct bpf_prog_info declaration into the loop,
> so it gets cleaned before each query.
>
> Reported-by: Lance Digby <[email protected]>
> Signed-off-by: Jiri Olsa <[email protected]>

Applied to bpf and added Fixes tags, thanks!