aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/name_table.c
diff options
context:
space:
mode:
authorJon Maloy <jon.maloy@ericsson.com>2018-04-11 22:52:09 +0200
committerDavid S. Miller <davem@davemloft.net>2018-04-12 21:46:10 -0400
commitc3317f4db831b7564ff8d1670326456a7fbbbcb3 (patch)
tree845a5dd46e764b071f8dedcf56233457ad10121b /net/tipc/name_table.c
parentlan78xx: PHY DSP registers initialization to address EEE link drop issues with long cables (diff)
downloadlinux-dev-c3317f4db831b7564ff8d1670326456a7fbbbcb3.tar.xz
linux-dev-c3317f4db831b7564ff8d1670326456a7fbbbcb3.zip
tipc: fix unbalanced reference counter
When a topology subscription is created, we may encounter (or KASAN may provoke) a failure to create a corresponding service instance in the binding table. Instead of letting the tipc_nametbl_subscribe() report the failure back to the caller, the function just makes a warning printout and returns, without incrementing the subscription reference counter as expected by the caller. This makes the caller believe that the subscription was successful, so it will at a later moment try to unsubscribe the item. This involves a sub_put() call. Since the reference counter never was incremented in the first place, we get a premature delete of the subscription item, followed by a "use-after-free" warning. We fix this by adding a return value to tipc_nametbl_subscribe() and make the caller aware of the failure to subscribe. This bug seems to always have been around, but this fix only applies back to the commit shown below. Given the low risk of this happening we believe this to be sufficient. Fixes: commit 218527fe27ad ("tipc: replace name table service range array with rb tree") Reported-by: syzbot+aa245f26d42b8305d157@syzkaller.appspotmail.com Signed-off-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc/name_table.c')
-rw-r--r--net/tipc/name_table.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index b1fe20972aa9..4068eaad61a6 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -665,13 +665,14 @@ int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower,
/**
* tipc_nametbl_subscribe - add a subscription object to the name table
*/
-void tipc_nametbl_subscribe(struct tipc_subscription *sub)
+bool tipc_nametbl_subscribe(struct tipc_subscription *sub)
{
struct name_table *nt = tipc_name_table(sub->net);
struct tipc_net *tn = tipc_net(sub->net);
struct tipc_subscr *s = &sub->evt.s;
u32 type = tipc_sub_read(s, seq.type);
struct tipc_service *sc;
+ bool res = true;
spin_lock_bh(&tn->nametbl_lock);
sc = tipc_service_find(sub->net, type);
@@ -685,8 +686,10 @@ void tipc_nametbl_subscribe(struct tipc_subscription *sub)
pr_warn("Failed to subscribe for {%u,%u,%u}\n", type,
tipc_sub_read(s, seq.lower),
tipc_sub_read(s, seq.upper));
+ res = false;
}
spin_unlock_bh(&tn->nametbl_lock);
+ return res;
}
/**