|
@@ -3732,6 +3732,25 @@ static bool tc_cls_act_is_valid_access(int off, int size,
|
|
return bpf_skb_is_valid_access(off, size, type, info);
|
|
return bpf_skb_is_valid_access(off, size, type, info);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool
|
|
|
|
+tc_cls_act_is_valid_access_analyzer(int off, int size,
|
|
|
|
+ enum bpf_access_type type,
|
|
|
|
+ struct bpf_insn_access_aux *info)
|
|
|
|
+{
|
|
|
|
+ switch (off) {
|
|
|
|
+ case offsetof(struct sk_buff, len):
|
|
|
|
+ return true;
|
|
|
|
+ case offsetof(struct sk_buff, data):
|
|
|
|
+ info->reg_type = PTR_TO_PACKET;
|
|
|
|
+ return true;
|
|
|
|
+ case offsetof(struct sk_buff, cb) +
|
|
|
|
+ offsetof(struct bpf_skb_data_end, data_end):
|
|
|
|
+ info->reg_type = PTR_TO_PACKET_END;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
static bool __is_valid_xdp_access(int off, int size)
|
|
static bool __is_valid_xdp_access(int off, int size)
|
|
{
|
|
{
|
|
if (off < 0 || off >= sizeof(struct xdp_md))
|
|
if (off < 0 || off >= sizeof(struct xdp_md))
|
|
@@ -3766,6 +3785,21 @@ static bool xdp_is_valid_access(int off, int size,
|
|
return __is_valid_xdp_access(off, size);
|
|
return __is_valid_xdp_access(off, size);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static bool xdp_is_valid_access_analyzer(int off, int size,
|
|
|
|
+ enum bpf_access_type type,
|
|
|
|
+ struct bpf_insn_access_aux *info)
|
|
|
|
+{
|
|
|
|
+ switch (off) {
|
|
|
|
+ case offsetof(struct xdp_buff, data):
|
|
|
|
+ info->reg_type = PTR_TO_PACKET;
|
|
|
|
+ return true;
|
|
|
|
+ case offsetof(struct xdp_buff, data_end):
|
|
|
|
+ info->reg_type = PTR_TO_PACKET_END;
|
|
|
|
+ return true;
|
|
|
|
+ }
|
|
|
|
+ return false;
|
|
|
|
+}
|
|
|
|
+
|
|
void bpf_warn_invalid_xdp_action(u32 act)
|
|
void bpf_warn_invalid_xdp_action(u32 act)
|
|
{
|
|
{
|
|
const u32 act_max = XDP_REDIRECT;
|
|
const u32 act_max = XDP_REDIRECT;
|
|
@@ -4395,68 +4429,103 @@ static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
|
|
return insn - insn_buf;
|
|
return insn - insn_buf;
|
|
}
|
|
}
|
|
|
|
|
|
-const struct bpf_verifier_ops sk_filter_prog_ops = {
|
|
|
|
|
|
+const struct bpf_verifier_ops sk_filter_verifier_ops = {
|
|
.get_func_proto = sk_filter_func_proto,
|
|
.get_func_proto = sk_filter_func_proto,
|
|
.is_valid_access = sk_filter_is_valid_access,
|
|
.is_valid_access = sk_filter_is_valid_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops tc_cls_act_prog_ops = {
|
|
|
|
|
|
+const struct bpf_prog_ops sk_filter_prog_ops = {
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_verifier_ops tc_cls_act_verifier_ops = {
|
|
.get_func_proto = tc_cls_act_func_proto,
|
|
.get_func_proto = tc_cls_act_func_proto,
|
|
.is_valid_access = tc_cls_act_is_valid_access,
|
|
.is_valid_access = tc_cls_act_is_valid_access,
|
|
.convert_ctx_access = tc_cls_act_convert_ctx_access,
|
|
.convert_ctx_access = tc_cls_act_convert_ctx_access,
|
|
.gen_prologue = tc_cls_act_prologue,
|
|
.gen_prologue = tc_cls_act_prologue,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_verifier_ops tc_cls_act_analyzer_ops = {
|
|
|
|
+ .is_valid_access = tc_cls_act_is_valid_access_analyzer,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_prog_ops tc_cls_act_prog_ops = {
|
|
.test_run = bpf_prog_test_run_skb,
|
|
.test_run = bpf_prog_test_run_skb,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops xdp_prog_ops = {
|
|
|
|
|
|
+const struct bpf_verifier_ops xdp_verifier_ops = {
|
|
.get_func_proto = xdp_func_proto,
|
|
.get_func_proto = xdp_func_proto,
|
|
.is_valid_access = xdp_is_valid_access,
|
|
.is_valid_access = xdp_is_valid_access,
|
|
.convert_ctx_access = xdp_convert_ctx_access,
|
|
.convert_ctx_access = xdp_convert_ctx_access,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_verifier_ops xdp_analyzer_ops = {
|
|
|
|
+ .is_valid_access = xdp_is_valid_access_analyzer,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_prog_ops xdp_prog_ops = {
|
|
.test_run = bpf_prog_test_run_xdp,
|
|
.test_run = bpf_prog_test_run_xdp,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops cg_skb_prog_ops = {
|
|
|
|
|
|
+const struct bpf_verifier_ops cg_skb_verifier_ops = {
|
|
.get_func_proto = sk_filter_func_proto,
|
|
.get_func_proto = sk_filter_func_proto,
|
|
.is_valid_access = sk_filter_is_valid_access,
|
|
.is_valid_access = sk_filter_is_valid_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_prog_ops cg_skb_prog_ops = {
|
|
.test_run = bpf_prog_test_run_skb,
|
|
.test_run = bpf_prog_test_run_skb,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops lwt_inout_prog_ops = {
|
|
|
|
|
|
+const struct bpf_verifier_ops lwt_inout_verifier_ops = {
|
|
.get_func_proto = lwt_inout_func_proto,
|
|
.get_func_proto = lwt_inout_func_proto,
|
|
.is_valid_access = lwt_is_valid_access,
|
|
.is_valid_access = lwt_is_valid_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_prog_ops lwt_inout_prog_ops = {
|
|
.test_run = bpf_prog_test_run_skb,
|
|
.test_run = bpf_prog_test_run_skb,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops lwt_xmit_prog_ops = {
|
|
|
|
|
|
+const struct bpf_verifier_ops lwt_xmit_verifier_ops = {
|
|
.get_func_proto = lwt_xmit_func_proto,
|
|
.get_func_proto = lwt_xmit_func_proto,
|
|
.is_valid_access = lwt_is_valid_access,
|
|
.is_valid_access = lwt_is_valid_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
.gen_prologue = tc_cls_act_prologue,
|
|
.gen_prologue = tc_cls_act_prologue,
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_prog_ops lwt_xmit_prog_ops = {
|
|
.test_run = bpf_prog_test_run_skb,
|
|
.test_run = bpf_prog_test_run_skb,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops cg_sock_prog_ops = {
|
|
|
|
|
|
+const struct bpf_verifier_ops cg_sock_verifier_ops = {
|
|
.get_func_proto = sock_filter_func_proto,
|
|
.get_func_proto = sock_filter_func_proto,
|
|
.is_valid_access = sock_filter_is_valid_access,
|
|
.is_valid_access = sock_filter_is_valid_access,
|
|
.convert_ctx_access = sock_filter_convert_ctx_access,
|
|
.convert_ctx_access = sock_filter_convert_ctx_access,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops sock_ops_prog_ops = {
|
|
|
|
|
|
+const struct bpf_prog_ops cg_sock_prog_ops = {
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_verifier_ops sock_ops_verifier_ops = {
|
|
.get_func_proto = sock_ops_func_proto,
|
|
.get_func_proto = sock_ops_func_proto,
|
|
.is_valid_access = sock_ops_is_valid_access,
|
|
.is_valid_access = sock_ops_is_valid_access,
|
|
.convert_ctx_access = sock_ops_convert_ctx_access,
|
|
.convert_ctx_access = sock_ops_convert_ctx_access,
|
|
};
|
|
};
|
|
|
|
|
|
-const struct bpf_verifier_ops sk_skb_prog_ops = {
|
|
|
|
|
|
+const struct bpf_prog_ops sock_ops_prog_ops = {
|
|
|
|
+};
|
|
|
|
+
|
|
|
|
+const struct bpf_verifier_ops sk_skb_verifier_ops = {
|
|
.get_func_proto = sk_skb_func_proto,
|
|
.get_func_proto = sk_skb_func_proto,
|
|
.is_valid_access = sk_skb_is_valid_access,
|
|
.is_valid_access = sk_skb_is_valid_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
.convert_ctx_access = bpf_convert_ctx_access,
|
|
.gen_prologue = sk_skb_prologue,
|
|
.gen_prologue = sk_skb_prologue,
|
|
};
|
|
};
|
|
|
|
|
|
|
|
+const struct bpf_prog_ops sk_skb_prog_ops = {
|
|
|
|
+};
|
|
|
|
+
|
|
int sk_detach_filter(struct sock *sk)
|
|
int sk_detach_filter(struct sock *sk)
|
|
{
|
|
{
|
|
int ret = -ENOENT;
|
|
int ret = -ENOENT;
|