Two BPF fixes
Subsystems (4)
Daniel Borkmann
maintainercover Two BPF fixes
The set fixes cb_access and xdp_adjust_head bits in struct bpf_prog, that are used for requirement checks on the program rather than f.e. heuristics. Thus, for tail calls, we cannot make any assumptions and are forced to set them.
Thanks!
Daniel Borkmann (2):
bpf: fix cb access in socket filter programs on tail calls
bpf: fix checking xdp_adjust_head on tail calls
kernel/bpf/syscall.c | 8 ++++++++ 1 file changed, 8 insertions(+)
Signature · 1 line
1.9.3
Daniel Borkmann
maintainerPATCH 1/2 bpf: fix cb access in socket filter programs on tail calls
Commit ff936a04e5f2 ("bpf: fix cb access in socket filter programs") added a fix for socket filter programs such that in i) AF_PACKET the 20 bytes of skb->cb[] area gets zeroed before use in order to not leak data, and ii) socket filter programs attached to TCP/UDP sockets need to save/restore these 20 bytes since they are also used by protocol layers at that time.
The problem is that bpf_prog_run_save_cb() and bpf_prog_run_clear_cb() only look at the actual attached program to determine whether to zero or save/restore the skb->cb[] parts. There can be cases where the actual attached program does not access the skb->cb[], but the program tail calls into another program which does access this area. In such a case, the zero or save/restore is currently not performed.
Since the programs we tail call into are unknown at verification time and can dynamically change, we need to assume that whenever the attached program performs a tail call, that later programs could access the skb->cb[], and therefore we need to always set cb_access to 1.
--- kernel/bpf/syscall.c | 7 +++++++ 1 file changed, 7 insertions(+)
kernel/bpf/syscall.c +7 -0
@@ -617,6 +617,13 @@ static void fixup_bpf_calls(struct bpf_prog *prog)if (insn->imm == BPF_FUNC_xdp_adjust_head) prog->xdp_adjust_head =1 ;if (insn->imm == BPF_FUNC_tail_call) { +/* If we tail call into other programs, we +* cannot make any assumptions since they +* can be replaced dynamically during runtime +* in the program array. +*/ + prog->cb_access =1 ; +/* mark bpf_tail_call as different opcode * to avoid conditional branch in * interpeter for every normal call
Signature · 1 line
1.9.3
Daniel Borkmann
maintainerPATCH 2/2 bpf: fix checking xdp_adjust_head on tail calls
In reply to Daniel BorkmannCommit 17bedab27231 ("bpf: xdp: Allow head adjustment in XDP prog") added the xdp_adjust_head bit to the BPF prog in order to tell drivers that the program that is to be attached requires support for the XDP bpf_xdp_adjust_head() helper such that drivers not supporting this helper can reject the program. There are also drivers that do support the helper, but need to check for xdp_adjust_head bit in order to move packet metadata prepended by the firmware away for making headroom.
For these cases, the current check for xdp_adjust_head bit is insufficient since there can be cases where the program itself does not use the bpf_xdp_adjust_head() helper, but tail calls into another program that uses bpf_xdp_adjust_head(). As such, the xdp_adjust_head bit is still set to 0. Since the first program has no control over which program it calls into, we need to assume that bpf_xdp_adjust_head() helper is used upon tail calls. Thus, for the very same reasons in cb_access, set the xdp_adjust_head bit to 1 when the main program uses tail calls.
--- kernel/bpf/syscall.c | 1 + 1 file changed, 1 insertion(+)
kernel/bpf/syscall.c +1 -0
@@ -623,6 +623,7 @@ static void fixup_bpf_calls(struct bpf_prog *prog)* in the program array. */ prog->cb_access =1 ; + prog->xdp_adjust_head =1 ;/* mark bpf_tail_call as different opcode * to avoid conditional branch in
Signature · 1 line
1.9.3
David Miller
maintainerFrom: Daniel Borkmann <[email protected]>
Date: Mon, 17 Apr 2017 03:12:05 +0200
Quoted 4 lines
The set fixes
cb_accessandxdp_adjust_headbits in structbpf_prog, that are used for requirement checks on the program rather than f.e. heuristics. Thus, for tail calls, we cannot make any assumptions and are forced to set them.
Series applied, thanks.
Tail calls bring up all kinds of caching and assumption issues, see my question in another thread about how register cached SKB parameters are handled in JITs across tail calls.