summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/uapi/linux/bpf.h1
-rw-r--r--kernel/bpf/verifier.c15
-rw-r--r--net/core/filter.c7
3 files changed, 21 insertions, 2 deletions
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 0248180bf2e2..3fa1af8a58d7 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -118,6 +118,7 @@ enum bpf_map_type {
118enum bpf_prog_type { 118enum bpf_prog_type {
119 BPF_PROG_TYPE_UNSPEC, 119 BPF_PROG_TYPE_UNSPEC,
120 BPF_PROG_TYPE_SOCKET_FILTER, 120 BPF_PROG_TYPE_SOCKET_FILTER,
121 BPF_PROG_TYPE_SCHED_CLS,
121}; 122};
122 123
123#define BPF_PSEUDO_MAP_FD 1 124#define BPF_PSEUDO_MAP_FD 1
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index a28e09c7825d..594d341f04db 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1172,6 +1172,17 @@ static int check_ld_imm(struct verifier_env *env, struct bpf_insn *insn)
1172 return 0; 1172 return 0;
1173} 1173}
1174 1174
1175static bool may_access_skb(enum bpf_prog_type type)
1176{
1177 switch (type) {
1178 case BPF_PROG_TYPE_SOCKET_FILTER:
1179 case BPF_PROG_TYPE_SCHED_CLS:
1180 return true;
1181 default:
1182 return false;
1183 }
1184}
1185
1175/* verify safety of LD_ABS|LD_IND instructions: 1186/* verify safety of LD_ABS|LD_IND instructions:
1176 * - they can only appear in the programs where ctx == skb 1187 * - they can only appear in the programs where ctx == skb
1177 * - since they are wrappers of function calls, they scratch R1-R5 registers, 1188 * - since they are wrappers of function calls, they scratch R1-R5 registers,
@@ -1194,8 +1205,8 @@ static int check_ld_abs(struct verifier_env *env, struct bpf_insn *insn)
1194 struct reg_state *reg; 1205 struct reg_state *reg;
1195 int i, err; 1206 int i, err;
1196 1207
1197 if (env->prog->aux->prog_type != BPF_PROG_TYPE_SOCKET_FILTER) { 1208 if (!may_access_skb(env->prog->aux->prog_type)) {
1198 verbose("BPF_LD_ABS|IND instructions are only allowed in socket filters\n"); 1209 verbose("BPF_LD_ABS|IND instructions not allowed for this program type\n");
1199 return -EINVAL; 1210 return -EINVAL;
1200 } 1211 }
1201 1212
diff --git a/net/core/filter.c b/net/core/filter.c
index 741721233166..514d4082f326 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -1166,9 +1166,16 @@ static struct bpf_prog_type_list sk_filter_type __read_mostly = {
1166 .type = BPF_PROG_TYPE_SOCKET_FILTER, 1166 .type = BPF_PROG_TYPE_SOCKET_FILTER,
1167}; 1167};
1168 1168
1169static struct bpf_prog_type_list sched_cls_type __read_mostly = {
1170 .ops = &sk_filter_ops,
1171 .type = BPF_PROG_TYPE_SCHED_CLS,
1172};
1173
1169static int __init register_sk_filter_ops(void) 1174static int __init register_sk_filter_ops(void)
1170{ 1175{
1171 bpf_register_prog_type(&sk_filter_type); 1176 bpf_register_prog_type(&sk_filter_type);
1177 bpf_register_prog_type(&sched_cls_type);
1178
1172 return 0; 1179 return 0;
1173} 1180}
1174late_initcall(register_sk_filter_ops); 1181late_initcall(register_sk_filter_ops);