]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob - queue-4.4/bpf-reject-wrong-sized-filters-earlier.patch
4.4-stable patches
[thirdparty/kernel/stable-queue.git] / queue-4.4 / bpf-reject-wrong-sized-filters-earlier.patch
1 From f7bd9e36ee4a4ce38e1cddd7effe6c0d9943285b Mon Sep 17 00:00:00 2001
2 From: Daniel Borkmann <daniel@iogearbox.net>
3 Date: Fri, 10 Jun 2016 21:19:07 +0200
4 Subject: bpf: reject wrong sized filters earlier
5
6 From: Daniel Borkmann <daniel@iogearbox.net>
7
8 commit f7bd9e36ee4a4ce38e1cddd7effe6c0d9943285b upstream.
9
10 Add a bpf_check_basics_ok() and reject filters that are of invalid
11 size much earlier, so we don't do any useless work such as invoking
12 bpf_prog_alloc(). Currently, rejection happens in bpf_check_classic()
13 only, but it's really unnecessarily late and they should be rejected
14 at earliest point. While at it, also clean up one bpf_prog_size() to
15 make it consistent with the remaining invocations.
16
17 Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
18 Acked-by: Alexei Starovoitov <ast@kernel.org>
19 Signed-off-by: David S. Miller <davem@davemloft.net>
20 Signed-off-by: Zubin Mithra <zsm@chromium.org>
21 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
22 ---
23 net/core/filter.c | 23 +++++++++++++++--------
24 1 file changed, 15 insertions(+), 8 deletions(-)
25
26 --- a/net/core/filter.c
27 +++ b/net/core/filter.c
28 @@ -742,6 +742,17 @@ static bool chk_code_allowed(u16 code_to
29 return codes[code_to_probe];
30 }
31
32 +static bool bpf_check_basics_ok(const struct sock_filter *filter,
33 + unsigned int flen)
34 +{
35 + if (filter == NULL)
36 + return false;
37 + if (flen == 0 || flen > BPF_MAXINSNS)
38 + return false;
39 +
40 + return true;
41 +}
42 +
43 /**
44 * bpf_check_classic - verify socket filter code
45 * @filter: filter to verify
46 @@ -762,9 +773,6 @@ static int bpf_check_classic(const struc
47 bool anc_found;
48 int pc;
49
50 - if (flen == 0 || flen > BPF_MAXINSNS)
51 - return -EINVAL;
52 -
53 /* Check the filter code now */
54 for (pc = 0; pc < flen; pc++) {
55 const struct sock_filter *ftest = &filter[pc];
56 @@ -1057,7 +1065,7 @@ int bpf_prog_create(struct bpf_prog **pf
57 struct bpf_prog *fp;
58
59 /* Make sure new filter is there and in the right amounts. */
60 - if (fprog->filter == NULL)
61 + if (!bpf_check_basics_ok(fprog->filter, fprog->len))
62 return -EINVAL;
63
64 fp = bpf_prog_alloc(bpf_prog_size(fprog->len), 0);
65 @@ -1104,7 +1112,7 @@ int bpf_prog_create_from_user(struct bpf
66 int err;
67
68 /* Make sure new filter is there and in the right amounts. */
69 - if (fprog->filter == NULL)
70 + if (!bpf_check_basics_ok(fprog->filter, fprog->len))
71 return -EINVAL;
72
73 fp = bpf_prog_alloc(bpf_prog_size(fprog->len), 0);
74 @@ -1184,7 +1192,6 @@ int __sk_attach_filter(struct sock_fprog
75 bool locked)
76 {
77 unsigned int fsize = bpf_classic_proglen(fprog);
78 - unsigned int bpf_fsize = bpf_prog_size(fprog->len);
79 struct bpf_prog *prog;
80 int err;
81
82 @@ -1192,10 +1199,10 @@ int __sk_attach_filter(struct sock_fprog
83 return -EPERM;
84
85 /* Make sure new filter is there and in the right amounts. */
86 - if (fprog->filter == NULL)
87 + if (!bpf_check_basics_ok(fprog->filter, fprog->len))
88 return -EINVAL;
89
90 - prog = bpf_prog_alloc(bpf_fsize, 0);
91 + prog = bpf_prog_alloc(bpf_prog_size(fprog->len), 0);
92 if (!prog)
93 return -ENOMEM;
94