Skip to content

Commit dd4bfda

Browse files
committed
Merge branch 'bpf-sk-msg-size-member'
John Fastabend says: ==================== This adds a size field to the sk_msg_md data structure used by SK_MSG programs. Without this in the zerocopy case and in the copy case where multiple iovs are in use its difficult to know how much data can be pulled in. The normal method of reading data and data_end only give the current contiguous buffer. BPF programs can attempt to pull in extra data but have to guess if it exists. This can result in multiple "guesses" its much better if we know upfront the size of the sk_msg. ==================== Acked-by: Martin KaFai Lau <kafai@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
2 parents 0bae2d4 + 945a47d commit dd4bfda

File tree

5 files changed

+24
-3
lines changed

5 files changed

+24
-3
lines changed

include/linux/skmsg.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ struct sk_msg_sg {
3636
struct scatterlist data[MAX_MSG_FRAGS + 1];
3737
};
3838

39+
/* UAPI in filter.c depends on struct sk_msg_sg being first element. If
40+
* this is moved filter.c also must be updated.
41+
*/
3942
struct sk_msg {
4043
struct sk_msg_sg sg;
4144
void *data;

include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,6 +2665,7 @@ struct sk_msg_md {
26652665
__u32 local_ip6[4]; /* Stored in network byte order */
26662666
__u32 remote_port; /* Stored in network byte order */
26672667
__u32 local_port; /* stored in host byte order */
2668+
__u32 size; /* Total size of sk_msg */
26682669
};
26692670

26702671
struct sk_reuseport_md {

net/core/filter.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7530,6 +7530,12 @@ static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
75307530
*insn++ = BPF_LDX_MEM(BPF_H, si->dst_reg, si->dst_reg,
75317531
offsetof(struct sock_common, skc_num));
75327532
break;
7533+
7534+
case offsetof(struct sk_msg_md, size):
7535+
*insn++ = BPF_LDX_MEM(BPF_FIELD_SIZEOF(struct sk_msg_sg, size),
7536+
si->dst_reg, si->src_reg,
7537+
offsetof(struct sk_msg_sg, size));
7538+
break;
75337539
}
75347540

75357541
return insn - insn_buf;

tools/include/uapi/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2665,6 +2665,7 @@ struct sk_msg_md {
26652665
__u32 local_ip6[4]; /* Stored in network byte order */
26662666
__u32 remote_port; /* Stored in network byte order */
26672667
__u32 local_port; /* stored in host byte order */
2668+
__u32 size; /* Total size of sk_msg */
26682669
};
26692670

26702671
struct sk_reuseport_md {

tools/testing/selftests/bpf/test_verifier.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1843,10 +1843,20 @@ static struct bpf_test tests[] = {
18431843
.prog_type = BPF_PROG_TYPE_SK_SKB,
18441844
},
18451845
{
1846-
"invalid 64B read of family in SK_MSG",
1846+
"valid access size in SK_MSG",
1847+
.insns = {
1848+
BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1,
1849+
offsetof(struct sk_msg_md, size)),
1850+
BPF_EXIT_INSN(),
1851+
},
1852+
.result = ACCEPT,
1853+
.prog_type = BPF_PROG_TYPE_SK_MSG,
1854+
},
1855+
{
1856+
"invalid 64B read of size in SK_MSG",
18471857
.insns = {
18481858
BPF_LDX_MEM(BPF_DW, BPF_REG_2, BPF_REG_1,
1849-
offsetof(struct sk_msg_md, family)),
1859+
offsetof(struct sk_msg_md, size)),
18501860
BPF_EXIT_INSN(),
18511861
},
18521862
.errstr = "invalid bpf_context access",
@@ -1857,7 +1867,7 @@ static struct bpf_test tests[] = {
18571867
"invalid read past end of SK_MSG",
18581868
.insns = {
18591869
BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1,
1860-
offsetof(struct sk_msg_md, local_port) + 4),
1870+
offsetof(struct sk_msg_md, size) + 4),
18611871
BPF_EXIT_INSN(),
18621872
},
18631873
.errstr = "R0 !read_ok",

0 commit comments

Comments
 (0)