diff options
author | Allan Stephens <allan.stephens@windriver.com> | 2010-08-17 11:00:07 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-08-17 17:31:53 -0700 |
commit | b02b69c8a403859ec72090742727e853d606a325 (patch) | |
tree | 6c46c41cc46fde8ea8a45d6265a3381556e0f84e /net/tipc/link.c | |
parent | f662c07058f7e6365ae65080d772f9122f6f50a9 (diff) | |
download | linux-3.10-b02b69c8a403859ec72090742727e853d606a325.tar.gz linux-3.10-b02b69c8a403859ec72090742727e853d606a325.tar.bz2 linux-3.10-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/link.c')
-rw-r--r-- | net/tipc/link.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/net/tipc/link.c b/net/tipc/link.c index a3616b99529..9d18c9b7638 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))) |