Skip to content

Commit b39b5f4

Browse files
liu-song-6Alexei Starovoitov
authored andcommitted
bpf: add cg_skb_is_valid_access for BPF_PROG_TYPE_CGROUP_SKB
BPF programs of BPF_PROG_TYPE_CGROUP_SKB need to access headers in the skb. This patch enables direct access of skb for these programs. Two helper functions bpf_compute_and_save_data_end() and bpf_restore_data_end() are introduced. There are used in __cgroup_bpf_run_filter_skb(), to compute proper data_end for the BPF program, and restore original data afterwards. Signed-off-by: Song Liu <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 2929ad2 commit b39b5f4

File tree

3 files changed

+62
-1
lines changed

3 files changed

+62
-1
lines changed

include/linux/filter.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,27 @@ static inline void bpf_compute_data_pointers(struct sk_buff *skb)
548548
cb->data_end = skb->data + skb_headlen(skb);
549549
}
550550

551+
/* Similar to bpf_compute_data_pointers(), except that save orginal
552+
* data in cb->data and cb->meta_data for restore.
553+
*/
554+
static inline void bpf_compute_and_save_data_end(
555+
struct sk_buff *skb, void **saved_data_end)
556+
{
557+
struct bpf_skb_data_end *cb = (struct bpf_skb_data_end *)skb->cb;
558+
559+
*saved_data_end = cb->data_end;
560+
cb->data_end = skb->data + skb_headlen(skb);
561+
}
562+
563+
/* Restore data saved by bpf_compute_data_pointers(). */
564+
static inline void bpf_restore_data_end(
565+
struct sk_buff *skb, void *saved_data_end)
566+
{
567+
struct bpf_skb_data_end *cb = (struct bpf_skb_data_end *)skb->cb;
568+
569+
cb->data_end = saved_data_end;
570+
}
571+
551572
static inline u8 *bpf_skb_cb(struct sk_buff *skb)
552573
{
553574
/* eBPF programs may read/write skb->cb[] area to transfer meta

kernel/bpf/cgroup.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,7 @@ int __cgroup_bpf_run_filter_skb(struct sock *sk,
553553
{
554554
unsigned int offset = skb->data - skb_network_header(skb);
555555
struct sock *save_sk;
556+
void *saved_data_end;
556557
struct cgroup *cgrp;
557558
int ret;
558559

@@ -566,8 +567,13 @@ int __cgroup_bpf_run_filter_skb(struct sock *sk,
566567
save_sk = skb->sk;
567568
skb->sk = sk;
568569
__skb_push(skb, offset);
570+
571+
/* compute pointers for the bpf prog */
572+
bpf_compute_and_save_data_end(skb, &saved_data_end);
573+
569574
ret = BPF_PROG_RUN_ARRAY(cgrp->bpf.effective[type], skb,
570575
bpf_prog_run_save_cb);
576+
bpf_restore_data_end(skb, saved_data_end);
571577
__skb_pull(skb, offset);
572578
skb->sk = save_sk;
573579
return ret == 1 ? 0 : -EPERM;

net/core/filter.c

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5352,6 +5352,40 @@ static bool sk_filter_is_valid_access(int off, int size,
53525352
return bpf_skb_is_valid_access(off, size, type, prog, info);
53535353
}
53545354

5355+
static bool cg_skb_is_valid_access(int off, int size,
5356+
enum bpf_access_type type,
5357+
const struct bpf_prog *prog,
5358+
struct bpf_insn_access_aux *info)
5359+
{
5360+
switch (off) {
5361+
case bpf_ctx_range(struct __sk_buff, tc_classid):
5362+
case bpf_ctx_range(struct __sk_buff, data_meta):
5363+
case bpf_ctx_range(struct __sk_buff, flow_keys):
5364+
return false;
5365+
}
5366+
if (type == BPF_WRITE) {
5367+
switch (off) {
5368+
case bpf_ctx_range(struct __sk_buff, mark):
5369+
case bpf_ctx_range(struct __sk_buff, priority):
5370+
case bpf_ctx_range_till(struct __sk_buff, cb[0], cb[4]):
5371+
break;
5372+
default:
5373+
return false;
5374+
}
5375+
}
5376+
5377+
switch (off) {
5378+
case bpf_ctx_range(struct __sk_buff, data):
5379+
info->reg_type = PTR_TO_PACKET;
5380+
break;
5381+
case bpf_ctx_range(struct __sk_buff, data_end):
5382+
info->reg_type = PTR_TO_PACKET_END;
5383+
break;
5384+
}
5385+
5386+
return bpf_skb_is_valid_access(off, size, type, prog, info);
5387+
}
5388+
53555389
static bool lwt_is_valid_access(int off, int size,
53565390
enum bpf_access_type type,
53575391
const struct bpf_prog *prog,
@@ -7044,7 +7078,7 @@ const struct bpf_prog_ops xdp_prog_ops = {
70447078

70457079
const struct bpf_verifier_ops cg_skb_verifier_ops = {
70467080
.get_func_proto = cg_skb_func_proto,
7047-
.is_valid_access = sk_filter_is_valid_access,
7081+
.is_valid_access = cg_skb_is_valid_access,
70487082
.convert_ctx_access = bpf_convert_ctx_access,
70497083
};
70507084

0 commit comments

Comments
 (0)