summaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorAllan Stephens <allan.stephens@windriver.com>2010-08-17 13:00:07 +0200
committerDavid S. Miller <davem@davemloft.net>2010-08-18 02:31:53 +0200
commitb02b69c8a403859ec72090742727e853d606a325 (patch)
tree6c46c41cc46fde8ea8a45d6265a3381556e0f84e /net/tipc
parenttipc: correct problems with misleading flags returned using poll() (diff)
downloadlinux-b02b69c8a403859ec72090742727e853d606a325.tar.xz
linux-b02b69c8a403859ec72090742727e853d606a325.zip
tipc: Check for disabled bearer when processing incoming messages
Add a check to tipc_recv_msg() to ensure it discards messages arriving on a newly disabled bearer. This is needed to deal with a race condition that can arise if the bearer is in the midst of being disabled when it receives a message. Performing the check after tipc_net_lock has been taken ensures that TIPC's bearers are in a stable state while the message is being processed. Signed-off-by: Allan Stephens <allan.stephens@windriver.com> Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/link.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c
index a3616b99529b..9d18c9b7638b 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -1802,6 +1802,15 @@ static int link_recv_buf_validate(struct sk_buff *buf)
return pskb_may_pull(buf, hdr_size);
}
+/**
+ * tipc_recv_msg - process TIPC messages arriving from off-node
+ * @head: pointer to message buffer chain
+ * @tb_ptr: pointer to bearer message arrived on
+ *
+ * Invoked with no locks held. Bearer pointer must point to a valid bearer
+ * structure (i.e. cannot be NULL), but bearer can be inactive.
+ */
+
void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
{
read_lock_bh(&tipc_net_lock);
@@ -1819,6 +1828,11 @@ void tipc_recv_msg(struct sk_buff *head, struct tipc_bearer *tb_ptr)
head = head->next;
+ /* Ensure bearer is still enabled */
+
+ if (unlikely(!b_ptr->active))
+ goto cont;
+
/* Ensure message is well-formed */
if (unlikely(!link_recv_buf_validate(buf)))