netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [patch net 0/2] net: sched: couple of chain fixes
@ 2017-08-22 20:46 Jiri Pirko
  2017-08-22 20:46 ` [patch net 1/2] net: sched: fix use after free when tcf_chain_destroy is called multiple times Jiri Pirko
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Jiri Pirko @ 2017-08-22 20:46 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

Jiri Pirko (2):
  net: sched: fix use after free when tcf_chain_destroy is called
    multiple times
  net: sched: don't do tcf_chain_flush from tcf_chain_destroy

 net/sched/cls_api.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

-- 
2.9.3

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [patch net 1/2] net: sched: fix use after free when tcf_chain_destroy is called multiple times
  2017-08-22 20:46 [patch net 0/2] net: sched: couple of chain fixes Jiri Pirko
@ 2017-08-22 20:46 ` Jiri Pirko
  2017-08-22 20:46 ` [patch net 2/2] net: sched: don't do tcf_chain_flush from tcf_chain_destroy Jiri Pirko
  2017-08-22 21:40 ` [patch net 0/2] net: sched: couple of chain fixes David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Jiri Pirko @ 2017-08-22 20:46 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

The goto_chain termination action takes a reference of a chain. In that
case, there is an issue when block_put is called tcf_chain_destroy
directly. The follo-up call of tcf_chain_put by goto_chain action free
works with memory that is already freed. This was caught by kasan:

[  220.337908] BUG: KASAN: use-after-free in tcf_chain_put+0x1b/0x50
[  220.344103] Read of size 4 at addr ffff88036d1f2cec by task systemd-journal/261
[  220.353047] CPU: 0 PID: 261 Comm: systemd-journal Not tainted 4.13.0-rc5jiri+ #54
[  220.360661] Hardware name: Mellanox Technologies Ltd. Mellanox switch/Mellanox x86 mezzanine board, BIOS 4.6.5 08/02/2016
[  220.371784] Call Trace:
[  220.374290]  <IRQ>
[  220.376355]  dump_stack+0xd5/0x150
[  220.391485]  print_address_description+0x86/0x410
[  220.396308]  kasan_report+0x181/0x4c0
[  220.415211]  tcf_chain_put+0x1b/0x50
[  220.418949]  free_tcf+0x95/0xc0

So allow tcf_chain_destroy to be called multiple times, free only in
case the reference count drops to 0.

Fixes: 5bc1701881e3 ("net: sched: introduce multichain support for filters")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_api.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 9fd44c2..45cd34e 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -215,9 +215,17 @@ static void tcf_chain_flush(struct tcf_chain *chain)
 
 static void tcf_chain_destroy(struct tcf_chain *chain)
 {
-	list_del(&chain->list);
+	/* May be already removed from the list by the previous call. */
+	if (!list_empty(&chain->list))
+		list_del_init(&chain->list);
+
 	tcf_chain_flush(chain);
-	kfree(chain);
+
+	/* There might still be a reference held when we got here from
+	 * tcf_block_put. Wait for the user to drop reference before free.
+	 */
+	if (!chain->refcnt)
+		kfree(chain);
 }
 
 struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [patch net 2/2] net: sched: don't do tcf_chain_flush from tcf_chain_destroy
  2017-08-22 20:46 [patch net 0/2] net: sched: couple of chain fixes Jiri Pirko
  2017-08-22 20:46 ` [patch net 1/2] net: sched: fix use after free when tcf_chain_destroy is called multiple times Jiri Pirko
@ 2017-08-22 20:46 ` Jiri Pirko
  2017-08-22 21:40 ` [patch net 0/2] net: sched: couple of chain fixes David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: Jiri Pirko @ 2017-08-22 20:46 UTC (permalink / raw)
  To: netdev; +Cc: davem, jhs, xiyou.wangcong, mlxsw

From: Jiri Pirko <jiri@mellanox.com>

tcf_chain_flush needs to be called with RTNL. However, on
free_tcf->
 tcf_action_goto_chain_fini->
  tcf_chain_put->
   tcf_chain_destroy->
    tcf_chain_flush
callpath, it is called without RTNL.
This issue was notified by following warning:

[  155.599052] WARNING: suspicious RCU usage
[  155.603165] 4.13.0-rc5jiri+ #54 Not tainted
[  155.607456] -----------------------------
[  155.611561] net/sched/cls_api.c:195 suspicious rcu_dereference_protected() usage!

Since on this callpath, the chain is guaranteed to be already empty
by check in tcf_chain_put, move the tcf_chain_flush call out and call it
only where it is needed - into tcf_block_put.

Fixes: db50514f9a9c ("net: sched: add termination action to allow goto chain")
Signed-off-by: Jiri Pirko <jiri@mellanox.com>
---
 net/sched/cls_api.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 45cd34e..6c5ea84 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -219,8 +219,6 @@ static void tcf_chain_destroy(struct tcf_chain *chain)
 	if (!list_empty(&chain->list))
 		list_del_init(&chain->list);
 
-	tcf_chain_flush(chain);
-
 	/* There might still be a reference held when we got here from
 	 * tcf_block_put. Wait for the user to drop reference before free.
 	 */
@@ -296,8 +294,10 @@ void tcf_block_put(struct tcf_block *block)
 	if (!block)
 		return;
 
-	list_for_each_entry_safe(chain, tmp, &block->chain_list, list)
+	list_for_each_entry_safe(chain, tmp, &block->chain_list, list) {
+		tcf_chain_flush(chain);
 		tcf_chain_destroy(chain);
+	}
 	kfree(block);
 }
 EXPORT_SYMBOL(tcf_block_put);
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [patch net 0/2] net: sched: couple of chain fixes
  2017-08-22 20:46 [patch net 0/2] net: sched: couple of chain fixes Jiri Pirko
  2017-08-22 20:46 ` [patch net 1/2] net: sched: fix use after free when tcf_chain_destroy is called multiple times Jiri Pirko
  2017-08-22 20:46 ` [patch net 2/2] net: sched: don't do tcf_chain_flush from tcf_chain_destroy Jiri Pirko
@ 2017-08-22 21:40 ` David Miller
  2 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2017-08-22 21:40 UTC (permalink / raw)
  To: jiri; +Cc: netdev, jhs, xiyou.wangcong, mlxsw

From: Jiri Pirko <jiri@resnulli.us>
Date: Tue, 22 Aug 2017 22:46:48 +0200

> From: Jiri Pirko <jiri@mellanox.com>
> 
> Jiri Pirko (2):
>   net: sched: fix use after free when tcf_chain_destroy is called
>     multiple times
>   net: sched: don't do tcf_chain_flush from tcf_chain_destroy

Series applied, thanks Jiri.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2017-08-22 21:40 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2017-08-22 20:46 [patch net 0/2] net: sched: couple of chain fixes Jiri Pirko
2017-08-22 20:46 ` [patch net 1/2] net: sched: fix use after free when tcf_chain_destroy is called multiple times Jiri Pirko
2017-08-22 20:46 ` [patch net 2/2] net: sched: don't do tcf_chain_flush from tcf_chain_destroy Jiri Pirko
2017-08-22 21:40 ` [patch net 0/2] net: sched: couple of chain fixes David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).