bpf: allow wide aligned loads for bpf_sock_addr user_ip6 and msg_src_ip6
authorStanislav Fomichev <sdf@google.com>
Mon, 15 Jul 2019 16:39:53 +0000 (09:39 -0700)
committerDaniel Borkmann <daniel@iogearbox.net>
Mon, 15 Jul 2019 21:15:53 +0000 (23:15 +0200)
Add explicit check for u64 loads of user_ip6 and msg_src_ip6 and
update the comment.

Cc: Yonghong Song <yhs@fb.com>
Signed-off-by: Stanislav Fomichev <sdf@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
include/uapi/linux/bpf.h
net/core/filter.c

index 6f68438..81be929 100644 (file)
@@ -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);
index c5983dd..0f6854c 100644 (file)
@@ -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 {