aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2018-08-02 00:32:30 -0400
committerDavid S. Miller <davem@davemloft.net>2018-08-02 00:32:30 -0400
commite6aed040eafb4ce1881bbc59a225f6b27d250396 (patch)
tree037b7aebd0b832999a44c34b70c4e2768509464c
parentc01f6c9b3207e52fc9973a066a856ddf7a0538d8 (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.c18
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
170static 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
182void fib6_info_destroy_rcu(struct rcu_head *head) 170void 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 }