]> git.ipfire.org Git - thirdparty/kernel/stable.git/commit
decnet: always not take dst->__refcnt when inserting dst into hash table
authorWei Wang <weiwan@google.com>
Fri, 16 Jun 2017 17:46:37 +0000 (10:46 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 5 Jul 2017 12:41:37 +0000 (14:41 +0200)
commitc207e0594f5dbb4c8d24118559c7142791360b88
treeab86d0c3c6bfe77615737057f956bd0edc871342
parent941bdec095d55e0127b4e3bce6e0ea73ee9f5462
decnet: always not take dst->__refcnt when inserting dst into hash table

[ Upstream commit 76371d2e3ad1f84426a30ebcd8c3b9b98f4c724f ]

In the existing dn_route.c code, dn_route_output_slow() takes
dst->__refcnt before calling dn_insert_route() while dn_route_input_slow()
does not take dst->__refcnt before calling dn_insert_route().
This makes the whole routing code very buggy.
In dn_dst_check_expire(), dnrt_free() is called when rt expires. This
makes the routes inserted by dn_route_output_slow() not able to be
freed as the refcnt is not released.
In dn_dst_gc(), dnrt_drop() is called to release rt which could
potentially cause the dst->__refcnt to be dropped to -1.
In dn_run_flush(), dst_free() is called to release all the dst. Again,
it makes the dst inserted by dn_route_output_slow() not able to be
released and also, it does not wait on the rcu and could potentially
cause crash in the path where other users still refer to this dst.

This patch makes sure both input and output path do not take
dst->__refcnt before calling dn_insert_route() and also makes sure
dnrt_free()/dst_free() is called when removing dst from the hash table.
The only difference between those 2 calls is that dnrt_free() waits on
the rcu while dst_free() does not.

Signed-off-by: Wei Wang <weiwan@google.com>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/decnet/dn_route.c