diff options
author | David S. Miller <davem@davemloft.net> | 2018-08-02 00:32:30 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-08-02 00:32:30 -0400 |
commit | e6aed040eafb4ce1881bbc59a225f6b27d250396 (patch) | |
tree | 037b7aebd0b832999a44c34b70c4e2768509464c | |
parent | c01f6c9b3207e52fc9973a066a856ddf7a0538d8 (diff) |
Revert "net/ipv6: fix metrics leak"
This reverts commit df18b50448fab1dff093731dfd0e25e77e1afcd1.
This change causes other problems and use-after-free situations as
found by syzbot.
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/ipv6/ip6_fib.c | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 211a2d437b56..d212738e9d10 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -167,22 +167,11 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags) | |||
167 | return f6i; | 167 | return f6i; |
168 | } | 168 | } |
169 | 169 | ||
170 | static void fib6_metrics_release(struct fib6_info *f6i) | ||
171 | { | ||
172 | struct dst_metrics *m; | ||
173 | |||
174 | if (!f6i) | ||
175 | return; | ||
176 | |||
177 | m = f6i->fib6_metrics; | ||
178 | if (m != &dst_default_metrics && refcount_dec_and_test(&m->refcnt)) | ||
179 | kfree(m); | ||
180 | } | ||
181 | |||
182 | void fib6_info_destroy_rcu(struct rcu_head *head) | 170 | void fib6_info_destroy_rcu(struct rcu_head *head) |
183 | { | 171 | { |
184 | struct fib6_info *f6i = container_of(head, struct fib6_info, rcu); | 172 | struct fib6_info *f6i = container_of(head, struct fib6_info, rcu); |
185 | struct rt6_exception_bucket *bucket; | 173 | struct rt6_exception_bucket *bucket; |
174 | struct dst_metrics *m; | ||
186 | 175 | ||
187 | WARN_ON(f6i->fib6_node); | 176 | WARN_ON(f6i->fib6_node); |
188 | 177 | ||
@@ -212,7 +201,9 @@ void fib6_info_destroy_rcu(struct rcu_head *head) | |||
212 | if (f6i->fib6_nh.nh_dev) | 201 | if (f6i->fib6_nh.nh_dev) |
213 | dev_put(f6i->fib6_nh.nh_dev); | 202 | dev_put(f6i->fib6_nh.nh_dev); |
214 | 203 | ||
215 | fib6_metrics_release(f6i); | 204 | m = f6i->fib6_metrics; |
205 | if (m != &dst_default_metrics && refcount_dec_and_test(&m->refcnt)) | ||
206 | kfree(m); | ||
216 | 207 | ||
217 | kfree(f6i); | 208 | kfree(f6i); |
218 | } | 209 | } |
@@ -896,7 +887,6 @@ static void fib6_drop_pcpu_from(struct fib6_info *f6i, | |||
896 | 887 | ||
897 | from = rcu_dereference_protected(pcpu_rt->from, | 888 | from = rcu_dereference_protected(pcpu_rt->from, |
898 | lockdep_is_held(&table->tb6_lock)); | 889 | lockdep_is_held(&table->tb6_lock)); |
899 | fib6_metrics_release(from); | ||
900 | rcu_assign_pointer(pcpu_rt->from, NULL); | 890 | rcu_assign_pointer(pcpu_rt->from, NULL); |
901 | fib6_info_release(from); | 891 | fib6_info_release(from); |
902 | } | 892 | } |