Skip to content

Commit 6dfb970

Browse files
netoptimizerdavem330
authored andcommitted
xdp: avoid leaking info stored in frame data on page reuse
The bpf infrastructure and verifier goes to great length to avoid bpf progs leaking kernel (pointer) info. For queueing an xdp_buff via XDP_REDIRECT, xdp_frame info stores kernel info (incl pointers) in top part of frame data (xdp->data_hard_start). Checks are in place to assure enough headroom is available for this. This info is not cleared, and if the frame is reused, then a malicious user could use bpf_xdp_adjust_head helper to move xdp->data into this area. Thus, making this area readable. This is not super critical as XDP progs requires root or CAP_SYS_ADMIN, which are privileged enough for such info. An effort (is underway) towards moving networking bpf hooks to the lesser privileged mode CAP_NET_ADMIN, where leaking such info should be avoided. Thus, this patch to clear the info when needed. Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 44fa2db commit 6dfb970

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

net/core/filter.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2692,6 +2692,7 @@ static unsigned long xdp_get_metalen(const struct xdp_buff *xdp)
26922692

26932693
BPF_CALL_2(bpf_xdp_adjust_head, struct xdp_buff *, xdp, int, offset)
26942694
{
2695+
void *xdp_frame_end = xdp->data_hard_start + sizeof(struct xdp_frame);
26952696
unsigned long metalen = xdp_get_metalen(xdp);
26962697
void *data_start = xdp->data_hard_start + metalen;
26972698
void *data = xdp->data + offset;
@@ -2700,6 +2701,13 @@ BPF_CALL_2(bpf_xdp_adjust_head, struct xdp_buff *, xdp, int, offset)
27002701
data > xdp->data_end - ETH_HLEN))
27012702
return -EINVAL;
27022703

2704+
/* Avoid info leak, when reusing area prev used by xdp_frame */
2705+
if (data < xdp_frame_end) {
2706+
unsigned long clearlen = xdp_frame_end - data;
2707+
2708+
memset(data, 0, clearlen);
2709+
}
2710+
27032711
if (metalen)
27042712
memmove(xdp->data_meta + offset,
27052713
xdp->data_meta, metalen);

0 commit comments

Comments
 (0)