| From: Kenny Yu <kennyyu@fb.com> |
| Date: Fri, 13 Jan 2017 08:58:34 -0800 |
| Subject: uprobe: Find last occurrence of ':' when parsing uprobe PATH:OFFSET |
| |
| commit 6496bb72bf20c1c7e4d6be44dfa663163e709116 upstream. |
| |
| Previously, `create_trace_uprobe` found the *first* occurence |
| of the ':' character when parsing `PATH:OFFSET` for a uprobe. |
| However, if the path contains a ':' character, then the function |
| would parse the path incorrectly. Even worse, if the path does not |
| exist, the subsequent call to `kern_path()` would set `ret` to |
| `ENOENT`, leading to very cryptic errno values in user space. |
| |
| The fix is to find the *last* occurence of ':'. |
| |
| How to repro:: The write fails with "No such file or directory", suggesting |
| incorrectly that the `uprobe_events` file does not exist. |
| |
| $ mkdir testing && cd testing |
| $ cp /bin/bash . |
| $ cp /bin/bash ./bash:with:colon |
| $ echo "p:uprobes/p__root_testing_bash_0x6 /root/testing/bash:0x6" > /sys/kernel/debug/tracing/uprobe_events # this works |
| $ echo "p:uprobes/p__root_testing_bash_with_colon_0x6 /root/testing/bash:with:colon:0x6" >> /sys/kernel/debug/tracing/uprobe_events # this doesn't |
| -bash: echo: write error: No such file or directory |
| |
| With the patch: |
| |
| $ echo "p:uprobes/p__root_testing_bash_0x6 /root/testing/bash:0x6" > /sys/kernel/debug/tracing/uprobe_events # this still works |
| $ echo "p:uprobes/p__root_testing_bash_with_colon_0x6 /root/testing/bash:with:colon:0x6" >> /sys/kernel/debug/tracing/uprobe_events # this works now too! |
| $ cat /sys/kernel/debug/tracing/uprobe_events |
| p:uprobes/p__root_testing_bash_0x6 /root/testing/bash:0x0000000000000006 |
| p:uprobes/p__root_testing_bash_with_colon_0x6 /root/testing/bash:with:colon:0x0000000000000006 |
| |
| Link: http://lkml.kernel.org/r/20170113165834.4081016-1-kennyyu@fb.com |
| |
| Signed-off-by: Kenny Yu <kennyyu@fb.com> |
| Reviewed-by: Omar Sandoval <osandov@fb.com> |
| Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| kernel/trace/trace_uprobe.c | 3 ++- |
| 1 file changed, 2 insertions(+), 1 deletion(-) |
| |
| --- a/kernel/trace/trace_uprobe.c |
| +++ b/kernel/trace/trace_uprobe.c |
| @@ -430,7 +430,8 @@ static int create_trace_uprobe(int argc, |
| pr_info("Probe point is not specified.\n"); |
| return -EINVAL; |
| } |
| - arg = strchr(argv[1], ':'); |
| + /* Find the last occurrence, in case the path contains ':' too. */ |
| + arg = strrchr(argv[1], ':'); |
| if (!arg) { |
| ret = -EINVAL; |
| goto fail_address_parse; |