diff options
author | Daniel Borkmann <daniel@iogearbox.net> | 2015-05-06 10:12:29 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-05-09 17:35:05 -0400 |
commit | 658da9379d0e1aa1e3e40c9b795357ada818b1c8 (patch) | |
tree | d867298c84e4ba073c195b1b8009c2a0d4a243da | |
parent | d9e12f42e58da475379b9080708b94f2095904af (diff) |
net: filter: add __GFP_NOWARN flag for larger kmem allocs
When seccomp BPF was added, it was discussed to add __GFP_NOWARN
flag for their configuration path as f.e. up to 32K allocations are
more prone to fail under stress. As we're going to reuse BPF API,
add __GFP_NOWARN flags where larger kmalloc() and friends allocations
could fail.
It doesn't make much sense to pass around __GFP_NOWARN everywhere as
an extra argument only for seccomp while we just as well could run
into similar issues for socket filters, where it's not desired to
have a user application throw a WARN() due to allocation failure.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: Nicolas Schichan <nschichan@freebox.fr>
Cc: Alexei Starovoitov <ast@plumgrid.com>
Cc: Kees Cook <keescook@chromium.org>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/core/filter.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index f887084740cd..45c015d6b974 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -371,7 +371,8 @@ static int bpf_convert_filter(struct sock_filter *prog, int len, | |||
371 | return -EINVAL; | 371 | return -EINVAL; |
372 | 372 | ||
373 | if (new_prog) { | 373 | if (new_prog) { |
374 | addrs = kcalloc(len, sizeof(*addrs), GFP_KERNEL); | 374 | addrs = kcalloc(len, sizeof(*addrs), |
375 | GFP_KERNEL | __GFP_NOWARN); | ||
375 | if (!addrs) | 376 | if (!addrs) |
376 | return -ENOMEM; | 377 | return -ENOMEM; |
377 | } | 378 | } |
@@ -839,7 +840,9 @@ static int bpf_prog_store_orig_filter(struct bpf_prog *fp, | |||
839 | 840 | ||
840 | fkprog = fp->orig_prog; | 841 | fkprog = fp->orig_prog; |
841 | fkprog->len = fprog->len; | 842 | fkprog->len = fprog->len; |
842 | fkprog->filter = kmemdup(fp->insns, fsize, GFP_KERNEL); | 843 | |
844 | fkprog->filter = kmemdup(fp->insns, fsize, | ||
845 | GFP_KERNEL | __GFP_NOWARN); | ||
843 | if (!fkprog->filter) { | 846 | if (!fkprog->filter) { |
844 | kfree(fp->orig_prog); | 847 | kfree(fp->orig_prog); |
845 | return -ENOMEM; | 848 | return -ENOMEM; |
@@ -941,7 +944,7 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp) | |||
941 | * pass. At this time, the user BPF is stored in fp->insns. | 944 | * pass. At this time, the user BPF is stored in fp->insns. |
942 | */ | 945 | */ |
943 | old_prog = kmemdup(fp->insns, old_len * sizeof(struct sock_filter), | 946 | old_prog = kmemdup(fp->insns, old_len * sizeof(struct sock_filter), |
944 | GFP_KERNEL); | 947 | GFP_KERNEL | __GFP_NOWARN); |
945 | if (!old_prog) { | 948 | if (!old_prog) { |
946 | err = -ENOMEM; | 949 | err = -ENOMEM; |
947 | goto out_err; | 950 | goto out_err; |