From b43995469e5804636a55372e9bbb17ccb22441c5 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 15 Jul 2019 09:39:52 -0700 Subject: bpf: rename bpf_ctx_wide_store_ok to bpf_ctx_wide_access_ok Rename bpf_ctx_wide_store_ok to bpf_ctx_wide_access_ok to indicate that it can be used for both loads and stores. Cc: Yonghong Song Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- include/linux/filter.h | 2 +- net/core/filter.c | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/include/linux/filter.h b/include/linux/filter.h index 6d944369ca87..ff65d22cf336 100644 --- a/include/linux/filter.h +++ b/include/linux/filter.h @@ -747,7 +747,7 @@ bpf_ctx_narrow_access_ok(u32 off, u32 size, u32 size_default) return size <= size_default && (size & (size - 1)) == 0; } -#define bpf_ctx_wide_store_ok(off, size, type, field) \ +#define bpf_ctx_wide_access_ok(off, size, type, field) \ (size == sizeof(__u64) && \ off >= offsetof(type, field) && \ off + sizeof(__u64) <= offsetofend(type, field) && \ diff --git a/net/core/filter.c b/net/core/filter.c index 47f6386fb17a..c5983ddb1a9f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6890,14 +6890,14 @@ static bool sock_addr_is_valid_access(int off, int size, if (!bpf_ctx_narrow_access_ok(off, size, size_default)) return false; } else { - if (bpf_ctx_wide_store_ok(off, size, - struct bpf_sock_addr, - user_ip6)) + if (bpf_ctx_wide_access_ok(off, size, + struct bpf_sock_addr, + user_ip6)) return true; - if (bpf_ctx_wide_store_ok(off, size, - struct bpf_sock_addr, - msg_src_ip6)) + if (bpf_ctx_wide_access_ok(off, size, + struct bpf_sock_addr, + msg_src_ip6)) return true; if (size != size_default) -- cgit v1.2.3 From d4ecfeb15494ec261fef2d25d96eecba66f0b182 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 15 Jul 2019 09:39:53 -0700 Subject: bpf: allow wide aligned loads for bpf_sock_addr user_ip6 and msg_src_ip6 Add explicit check for u64 loads of user_ip6 and msg_src_ip6 and update the comment. Cc: Yonghong Song Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- include/uapi/linux/bpf.h | 4 ++-- net/core/filter.c | 12 +++++++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 6f68438aa4ed..81be929b89fc 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -3248,7 +3248,7 @@ struct bpf_sock_addr { __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write. * Stored in network byte order. */ - __u32 user_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. + __u32 user_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write. * Stored in network byte order. */ __u32 user_port; /* Allows 4-byte read and write. @@ -3260,7 +3260,7 @@ struct bpf_sock_addr { __u32 msg_src_ip4; /* Allows 1,2,4-byte read and 4-byte write. * Stored in network byte order. */ - __u32 msg_src_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. + __u32 msg_src_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write. * Stored in network byte order. */ __bpf_md_ptr(struct bpf_sock *, sk); diff --git a/net/core/filter.c b/net/core/filter.c index c5983ddb1a9f..0f6854ccf894 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -6884,9 +6884,19 @@ static bool sock_addr_is_valid_access(int off, int size, case bpf_ctx_range(struct bpf_sock_addr, msg_src_ip4): case bpf_ctx_range_till(struct bpf_sock_addr, msg_src_ip6[0], msg_src_ip6[3]): - /* Only narrow read access allowed for now. */ if (type == BPF_READ) { bpf_ctx_record_field_size(info, size_default); + + if (bpf_ctx_wide_access_ok(off, size, + struct bpf_sock_addr, + user_ip6)) + return true; + + if (bpf_ctx_wide_access_ok(off, size, + struct bpf_sock_addr, + msg_src_ip6)) + return true; + if (!bpf_ctx_narrow_access_ok(off, size, size_default)) return false; } else { -- cgit v1.2.3 From 8b45063c8584b3e6caff0b109dd0f47b35487aba Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 15 Jul 2019 09:39:54 -0700 Subject: selftests/bpf: rename verifier/wide_store.c to verifier/wide_access.c Move the file and rename internal BPF_SOCK_ADDR define to BPF_SOCK_ADDR_STORE. This selftest will be extended in the next commit with the wide loads. Cc: Yonghong Song Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/verifier/wide_access.c | 36 ++++++++++++++++++++++ tools/testing/selftests/bpf/verifier/wide_store.c | 36 ---------------------- 2 files changed, 36 insertions(+), 36 deletions(-) create mode 100644 tools/testing/selftests/bpf/verifier/wide_access.c delete mode 100644 tools/testing/selftests/bpf/verifier/wide_store.c diff --git a/tools/testing/selftests/bpf/verifier/wide_access.c b/tools/testing/selftests/bpf/verifier/wide_access.c new file mode 100644 index 000000000000..3ac97328432f --- /dev/null +++ b/tools/testing/selftests/bpf/verifier/wide_access.c @@ -0,0 +1,36 @@ +#define BPF_SOCK_ADDR_STORE(field, off, res, err) \ +{ \ + "wide store to bpf_sock_addr." #field "[" #off "]", \ + .insns = { \ + BPF_MOV64_IMM(BPF_REG_0, 1), \ + BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \ + offsetof(struct bpf_sock_addr, field[off])), \ + BPF_EXIT_INSN(), \ + }, \ + .result = res, \ + .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ + .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ + .errstr = err, \ +} + +/* user_ip6[0] is u64 aligned */ +BPF_SOCK_ADDR_STORE(user_ip6, 0, ACCEPT, + NULL), +BPF_SOCK_ADDR_STORE(user_ip6, 1, REJECT, + "invalid bpf_context access off=12 size=8"), +BPF_SOCK_ADDR_STORE(user_ip6, 2, ACCEPT, + NULL), +BPF_SOCK_ADDR_STORE(user_ip6, 3, REJECT, + "invalid bpf_context access off=20 size=8"), + +/* msg_src_ip6[0] is _not_ u64 aligned */ +BPF_SOCK_ADDR_STORE(msg_src_ip6, 0, REJECT, + "invalid bpf_context access off=44 size=8"), +BPF_SOCK_ADDR_STORE(msg_src_ip6, 1, ACCEPT, + NULL), +BPF_SOCK_ADDR_STORE(msg_src_ip6, 2, REJECT, + "invalid bpf_context access off=52 size=8"), +BPF_SOCK_ADDR_STORE(msg_src_ip6, 3, REJECT, + "invalid bpf_context access off=56 size=8"), + +#undef BPF_SOCK_ADDR_STORE diff --git a/tools/testing/selftests/bpf/verifier/wide_store.c b/tools/testing/selftests/bpf/verifier/wide_store.c deleted file mode 100644 index 8fe99602ded4..000000000000 --- a/tools/testing/selftests/bpf/verifier/wide_store.c +++ /dev/null @@ -1,36 +0,0 @@ -#define BPF_SOCK_ADDR(field, off, res, err) \ -{ \ - "wide store to bpf_sock_addr." #field "[" #off "]", \ - .insns = { \ - BPF_MOV64_IMM(BPF_REG_0, 1), \ - BPF_STX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, \ - offsetof(struct bpf_sock_addr, field[off])), \ - BPF_EXIT_INSN(), \ - }, \ - .result = res, \ - .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ - .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ - .errstr = err, \ -} - -/* user_ip6[0] is u64 aligned */ -BPF_SOCK_ADDR(user_ip6, 0, ACCEPT, - NULL), -BPF_SOCK_ADDR(user_ip6, 1, REJECT, - "invalid bpf_context access off=12 size=8"), -BPF_SOCK_ADDR(user_ip6, 2, ACCEPT, - NULL), -BPF_SOCK_ADDR(user_ip6, 3, REJECT, - "invalid bpf_context access off=20 size=8"), - -/* msg_src_ip6[0] is _not_ u64 aligned */ -BPF_SOCK_ADDR(msg_src_ip6, 0, REJECT, - "invalid bpf_context access off=44 size=8"), -BPF_SOCK_ADDR(msg_src_ip6, 1, ACCEPT, - NULL), -BPF_SOCK_ADDR(msg_src_ip6, 2, REJECT, - "invalid bpf_context access off=52 size=8"), -BPF_SOCK_ADDR(msg_src_ip6, 3, REJECT, - "invalid bpf_context access off=56 size=8"), - -#undef BPF_SOCK_ADDR -- cgit v1.2.3 From 7dd8d6119d481da1c4619eb7d8cfef33edfbee81 Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 15 Jul 2019 09:39:55 -0700 Subject: selftests/bpf: add selftests for wide loads Mirror existing wide store tests with wide loads. The only significant difference is expected error string. Cc: Yonghong Song Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/testing/selftests/bpf/verifier/wide_access.c | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tools/testing/selftests/bpf/verifier/wide_access.c b/tools/testing/selftests/bpf/verifier/wide_access.c index 3ac97328432f..ccade9312d21 100644 --- a/tools/testing/selftests/bpf/verifier/wide_access.c +++ b/tools/testing/selftests/bpf/verifier/wide_access.c @@ -34,3 +34,40 @@ BPF_SOCK_ADDR_STORE(msg_src_ip6, 3, REJECT, "invalid bpf_context access off=56 size=8"), #undef BPF_SOCK_ADDR_STORE + +#define BPF_SOCK_ADDR_LOAD(field, off, res, err) \ +{ \ + "wide load from bpf_sock_addr." #field "[" #off "]", \ + .insns = { \ + BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_1, \ + offsetof(struct bpf_sock_addr, field[off])), \ + BPF_MOV64_IMM(BPF_REG_0, 1), \ + BPF_EXIT_INSN(), \ + }, \ + .result = res, \ + .prog_type = BPF_PROG_TYPE_CGROUP_SOCK_ADDR, \ + .expected_attach_type = BPF_CGROUP_UDP6_SENDMSG, \ + .errstr = err, \ +} + +/* user_ip6[0] is u64 aligned */ +BPF_SOCK_ADDR_LOAD(user_ip6, 0, ACCEPT, + NULL), +BPF_SOCK_ADDR_LOAD(user_ip6, 1, REJECT, + "invalid bpf_context access off=12 size=8"), +BPF_SOCK_ADDR_LOAD(user_ip6, 2, ACCEPT, + NULL), +BPF_SOCK_ADDR_LOAD(user_ip6, 3, REJECT, + "invalid bpf_context access off=20 size=8"), + +/* msg_src_ip6[0] is _not_ u64 aligned */ +BPF_SOCK_ADDR_LOAD(msg_src_ip6, 0, REJECT, + "invalid bpf_context access off=44 size=8"), +BPF_SOCK_ADDR_LOAD(msg_src_ip6, 1, ACCEPT, + NULL), +BPF_SOCK_ADDR_LOAD(msg_src_ip6, 2, REJECT, + "invalid bpf_context access off=52 size=8"), +BPF_SOCK_ADDR_LOAD(msg_src_ip6, 3, REJECT, + "invalid bpf_context access off=56 size=8"), + +#undef BPF_SOCK_ADDR_LOAD -- cgit v1.2.3 From 073a4834a81368c8af9cc9e99ff83245600a8f6b Mon Sep 17 00:00:00 2001 From: Stanislav Fomichev Date: Mon, 15 Jul 2019 09:39:56 -0700 Subject: bpf: sync bpf.h to tools/ Update bpf_sock_addr comments to indicate support for 8-byte reads from user_ip6 and msg_src_ip6. Cc: Yonghong Song Signed-off-by: Stanislav Fomichev Signed-off-by: Daniel Borkmann --- tools/include/uapi/linux/bpf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index f506c68b2612..1f61374fcf81 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -3245,7 +3245,7 @@ struct bpf_sock_addr { __u32 user_ip4; /* Allows 1,2,4-byte read and 4-byte write. * Stored in network byte order. */ - __u32 user_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. + __u32 user_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write. * Stored in network byte order. */ __u32 user_port; /* Allows 4-byte read and write. @@ -3257,7 +3257,7 @@ struct bpf_sock_addr { __u32 msg_src_ip4; /* Allows 1,2,4-byte read and 4-byte write. * Stored in network byte order. */ - __u32 msg_src_ip6[4]; /* Allows 1,2,4-byte read and 4,8-byte write. + __u32 msg_src_ip6[4]; /* Allows 1,2,4,8-byte read and 4,8-byte write. * Stored in network byte order. */ __bpf_md_ptr(struct bpf_sock *, sk); -- cgit v1.2.3