diff options
author | Cong Wang <xiyou.wangcong@gmail.com> | 2018-02-05 17:41:45 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-02-06 18:58:57 -0500 |
commit | 7dc68e98757a8eccf8ca7a53a29b896f1eef1f76 (patch) | |
tree | d7ccfe10125fd7b843b55579d7ff5b8d11744850 | |
parent | 992cfc7c5d105094da7c21c9c74d97ac26bb1e56 (diff) |
netfilter: xt_RATEEST: acquire xt_rateest_mutex for hash insert
rateest_hash is supposed to be protected by xt_rateest_mutex,
and, as suggested by Eric, lookup and insert should be atomic,
so we should acquire the xt_rateest_mutex once for both.
So introduce a non-locking helper for internal use and keep the
locking one for external.
Reported-by: <syzbot+5cb189720978275e4c75@syzkaller.appspotmail.com>
Fixes: 5859034d7eb8 ("[NETFILTER]: x_tables: add RATEEST target")
Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com>
Reviewed-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/netfilter/xt_RATEEST.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/net/netfilter/xt_RATEEST.c b/net/netfilter/xt_RATEEST.c index 498b54fd04d7..141c295191f6 100644 --- a/net/netfilter/xt_RATEEST.c +++ b/net/netfilter/xt_RATEEST.c | |||
@@ -39,23 +39,31 @@ static void xt_rateest_hash_insert(struct xt_rateest *est) | |||
39 | hlist_add_head(&est->list, &rateest_hash[h]); | 39 | hlist_add_head(&est->list, &rateest_hash[h]); |
40 | } | 40 | } |
41 | 41 | ||
42 | struct xt_rateest *xt_rateest_lookup(const char *name) | 42 | static struct xt_rateest *__xt_rateest_lookup(const char *name) |
43 | { | 43 | { |
44 | struct xt_rateest *est; | 44 | struct xt_rateest *est; |
45 | unsigned int h; | 45 | unsigned int h; |
46 | 46 | ||
47 | h = xt_rateest_hash(name); | 47 | h = xt_rateest_hash(name); |
48 | mutex_lock(&xt_rateest_mutex); | ||
49 | hlist_for_each_entry(est, &rateest_hash[h], list) { | 48 | hlist_for_each_entry(est, &rateest_hash[h], list) { |
50 | if (strcmp(est->name, name) == 0) { | 49 | if (strcmp(est->name, name) == 0) { |
51 | est->refcnt++; | 50 | est->refcnt++; |
52 | mutex_unlock(&xt_rateest_mutex); | ||
53 | return est; | 51 | return est; |
54 | } | 52 | } |
55 | } | 53 | } |
56 | mutex_unlock(&xt_rateest_mutex); | 54 | |
57 | return NULL; | 55 | return NULL; |
58 | } | 56 | } |
57 | |||
58 | struct xt_rateest *xt_rateest_lookup(const char *name) | ||
59 | { | ||
60 | struct xt_rateest *est; | ||
61 | |||
62 | mutex_lock(&xt_rateest_mutex); | ||
63 | est = __xt_rateest_lookup(name); | ||
64 | mutex_unlock(&xt_rateest_mutex); | ||
65 | return est; | ||
66 | } | ||
59 | EXPORT_SYMBOL_GPL(xt_rateest_lookup); | 67 | EXPORT_SYMBOL_GPL(xt_rateest_lookup); |
60 | 68 | ||
61 | void xt_rateest_put(struct xt_rateest *est) | 69 | void xt_rateest_put(struct xt_rateest *est) |
@@ -100,8 +108,10 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) | |||
100 | 108 | ||
101 | net_get_random_once(&jhash_rnd, sizeof(jhash_rnd)); | 109 | net_get_random_once(&jhash_rnd, sizeof(jhash_rnd)); |
102 | 110 | ||
103 | est = xt_rateest_lookup(info->name); | 111 | mutex_lock(&xt_rateest_mutex); |
112 | est = __xt_rateest_lookup(info->name); | ||
104 | if (est) { | 113 | if (est) { |
114 | mutex_unlock(&xt_rateest_mutex); | ||
105 | /* | 115 | /* |
106 | * If estimator parameters are specified, they must match the | 116 | * If estimator parameters are specified, they must match the |
107 | * existing estimator. | 117 | * existing estimator. |
@@ -139,11 +149,13 @@ static int xt_rateest_tg_checkentry(const struct xt_tgchk_param *par) | |||
139 | 149 | ||
140 | info->est = est; | 150 | info->est = est; |
141 | xt_rateest_hash_insert(est); | 151 | xt_rateest_hash_insert(est); |
152 | mutex_unlock(&xt_rateest_mutex); | ||
142 | return 0; | 153 | return 0; |
143 | 154 | ||
144 | err2: | 155 | err2: |
145 | kfree(est); | 156 | kfree(est); |
146 | err1: | 157 | err1: |
158 | mutex_unlock(&xt_rateest_mutex); | ||
147 | return ret; | 159 | return ret; |
148 | } | 160 | } |
149 | 161 | ||