Patch "libbpf: detect broken PID filtering logic for multi-uprobe" has been added to the 6.9-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    libbpf: detect broken PID filtering logic for multi-uprobe

to the 6.9-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     libbpf-detect-broken-pid-filtering-logic-for-multi-u.patch
and it can be found in the queue-6.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit cb17ed4e46cc33591249bb8a2002e900e27013aa
Author: Andrii Nakryiko <andrii@xxxxxxxxxx>
Date:   Tue May 21 09:33:59 2024 -0700

    libbpf: detect broken PID filtering logic for multi-uprobe
    
    [ Upstream commit 04d939a2ab229a3821f04fc81f7c027842f501f1 ]
    
    Libbpf is automatically (and transparently to user) detecting
    multi-uprobe support in the kernel, and, if supported, uses
    multi-uprobes to improve USDT attachment speed.
    
    USDTs can be attached system-wide or for the specific process by PID. In
    the latter case, we rely on correct kernel logic of not triggering USDT
    for unrelated processes.
    
    As such, on older kernels that do support multi-uprobes, but still have
    broken PID filtering logic, we need to fall back to singular uprobes.
    
    Unfortunately, whether user is using PID filtering or not is known at
    the attachment time, which happens after relevant BPF programs were
    loaded into the kernel. Also unfortunately, we need to make a call
    whether to use multi-uprobes or singular uprobe for SEC("usdt") programs
    during BPF object load time, at which point we have no information about
    possible PID filtering.
    
    The distinction between single and multi-uprobes is small, but important
    for the kernel. Multi-uprobes get BPF_TRACE_UPROBE_MULTI attach type,
    and kernel internally substitiute different implementation of some of
    BPF helpers (e.g., bpf_get_attach_cookie()) depending on whether uprobe
    is multi or singular. So, multi-uprobes and singular uprobes cannot be
    intermixed.
    
    All the above implies that we have to make an early and conservative
    call about the use of multi-uprobes. And so this patch modifies libbpf's
    existing feature detector for multi-uprobe support to also check correct
    PID filtering. If PID filtering is not yet fixed, we fall back to
    singular uprobes for USDTs.
    
    This extension to feature detection is simple thanks to kernel's -EINVAL
    addition for pid < 0.
    
    Acked-by: Jiri Olsa <jolsa@xxxxxxxxxx>
    Signed-off-by: Andrii Nakryiko <andrii@xxxxxxxxxx>
    Link: https://lore.kernel.org/r/20240521163401.3005045-4-andrii@xxxxxxxxxx
    Signed-off-by: Alexei Starovoitov <ast@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/tools/lib/bpf/features.c b/tools/lib/bpf/features.c
index a336786a22a38..3df0125ed5fa7 100644
--- a/tools/lib/bpf/features.c
+++ b/tools/lib/bpf/features.c
@@ -392,11 +392,40 @@ static int probe_uprobe_multi_link(int token_fd)
 	link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts);
 	err = -errno; /* close() can clobber errno */
 
+	if (link_fd >= 0 || err != -EBADF) {
+		close(link_fd);
+		close(prog_fd);
+		return 0;
+	}
+
+	/* Initial multi-uprobe support in kernel didn't handle PID filtering
+	 * correctly (it was doing thread filtering, not process filtering).
+	 * So now we'll detect if PID filtering logic was fixed, and, if not,
+	 * we'll pretend multi-uprobes are not supported, if not.
+	 * Multi-uprobes are used in USDT attachment logic, and we need to be
+	 * conservative here, because multi-uprobe selection happens early at
+	 * load time, while the use of PID filtering is known late at
+	 * attachment time, at which point it's too late to undo multi-uprobe
+	 * selection.
+	 *
+	 * Creating uprobe with pid == -1 for (invalid) '/' binary will fail
+	 * early with -EINVAL on kernels with fixed PID filtering logic;
+	 * otherwise -ESRCH would be returned if passed correct binary path
+	 * (but we'll just get -BADF, of course).
+	 */
+	link_opts.uprobe_multi.pid = -1; /* invalid PID */
+	link_opts.uprobe_multi.path = "/"; /* invalid path */
+	link_opts.uprobe_multi.offsets = &offset;
+	link_opts.uprobe_multi.cnt = 1;
+
+	link_fd = bpf_link_create(prog_fd, -1, BPF_TRACE_UPROBE_MULTI, &link_opts);
+	err = -errno; /* close() can clobber errno */
+
 	if (link_fd >= 0)
 		close(link_fd);
 	close(prog_fd);
 
-	return link_fd < 0 && err == -EBADF;
+	return link_fd < 0 && err == -EINVAL;
 }
 
 static int probe_kern_bpf_cookie(int token_fd)




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux