diff options
| author | Mauricio Vasquez B <mauricio.vasquez@polito.it> | 2018-06-29 08:48:20 -0400 |
|---|---|---|
| committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-07-03 17:26:28 -0400 |
| commit | ed2b82c03dc187018307c7c6bf9299705f3db383 (patch) | |
| tree | 4a208a727bd13dee13aad3b7202b259a6ed4aa5d /kernel | |
| parent | 39d393cf209697babc53f8b29e6aecd6acd8509e (diff) | |
bpf: hash map: decrement counter on error
Decrement the number of elements in the map in case the allocation
of a new node fails.
Fixes: 6c9059817432 ("bpf: pre-allocate hash map elements")
Signed-off-by: Mauricio Vasquez B <mauricio.vasquez@polito.it>
Acked-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/hashtab.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c index 3ca2198a6d22..513d9dfcf4ee 100644 --- a/kernel/bpf/hashtab.c +++ b/kernel/bpf/hashtab.c | |||
| @@ -747,13 +747,15 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | |||
| 747 | * old element will be freed immediately. | 747 | * old element will be freed immediately. |
| 748 | * Otherwise return an error | 748 | * Otherwise return an error |
| 749 | */ | 749 | */ |
| 750 | atomic_dec(&htab->count); | 750 | l_new = ERR_PTR(-E2BIG); |
| 751 | return ERR_PTR(-E2BIG); | 751 | goto dec_count; |
| 752 | } | 752 | } |
| 753 | l_new = kmalloc_node(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN, | 753 | l_new = kmalloc_node(htab->elem_size, GFP_ATOMIC | __GFP_NOWARN, |
| 754 | htab->map.numa_node); | 754 | htab->map.numa_node); |
| 755 | if (!l_new) | 755 | if (!l_new) { |
| 756 | return ERR_PTR(-ENOMEM); | 756 | l_new = ERR_PTR(-ENOMEM); |
| 757 | goto dec_count; | ||
| 758 | } | ||
| 757 | } | 759 | } |
| 758 | 760 | ||
| 759 | memcpy(l_new->key, key, key_size); | 761 | memcpy(l_new->key, key, key_size); |
| @@ -766,7 +768,8 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | |||
| 766 | GFP_ATOMIC | __GFP_NOWARN); | 768 | GFP_ATOMIC | __GFP_NOWARN); |
| 767 | if (!pptr) { | 769 | if (!pptr) { |
| 768 | kfree(l_new); | 770 | kfree(l_new); |
| 769 | return ERR_PTR(-ENOMEM); | 771 | l_new = ERR_PTR(-ENOMEM); |
| 772 | goto dec_count; | ||
| 770 | } | 773 | } |
| 771 | } | 774 | } |
| 772 | 775 | ||
| @@ -780,6 +783,9 @@ static struct htab_elem *alloc_htab_elem(struct bpf_htab *htab, void *key, | |||
| 780 | 783 | ||
| 781 | l_new->hash = hash; | 784 | l_new->hash = hash; |
| 782 | return l_new; | 785 | return l_new; |
| 786 | dec_count: | ||
| 787 | atomic_dec(&htab->count); | ||
| 788 | return l_new; | ||
| 783 | } | 789 | } |
| 784 | 790 | ||
| 785 | static int check_flags(struct bpf_htab *htab, struct htab_elem *l_old, | 791 | static int check_flags(struct bpf_htab *htab, struct htab_elem *l_old, |
