aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
authorParthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com>2016-02-02 04:52:12 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-06 03:41:58 -0500
commitc8beccc67c833db4a01c621cbc6eb0a577286806 (patch)
tree88417ce5ac52d5186d9b0065b0ef159cbc159dc7 /net/tipc
parent7c13c6224123a6424bd3bc60ef982759754501e9 (diff)
tipc: fix connection abort during subscription cancellation
In 'commit 7fe8097cef5f ("tipc: fix nullpointer bug when subscribing to events")', we terminate the connection if the subscription creation fails. In the same commit, the subscription creation result was based on the value of subscription pointer (set in the function) instead of the return code. Unfortunately, the same function also handles subscription cancellation request. For a subscription cancellation request, the subscription pointer cannot be set. Thus the connection is terminated during cancellation request. In this commit, we move the subcription cancel check outside of tipc_subscrp_create(). Hence, - tipc_subscrp_create() will create a subscripton - tipc_subscrb_rcv_cb() will subscribe or cancel a subscription. Fixes: 'commit 7fe8097cef5f ("tipc: fix nullpointer bug when subscribing to events")' Acked-by: Ying Xue <ying.xue@windriver.com> Reviewed-by: Jon Maloy <jon.maloy@ericsson.com> Signed-off-by: Parthasarathy Bhuvaragan <parthasarathy.bhuvaragan@ericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/subscr.c38
1 files changed, 19 insertions, 19 deletions
diff --git a/net/tipc/subscr.c b/net/tipc/subscr.c
index 022a2f21be04..531227208ae2 100644
--- a/net/tipc/subscr.c
+++ b/net/tipc/subscr.c
@@ -235,22 +235,11 @@ static void tipc_subscrp_cancel(struct tipc_subscr *s,
235 235
236static struct tipc_subscription *tipc_subscrp_create(struct net *net, 236static struct tipc_subscription *tipc_subscrp_create(struct net *net,
237 struct tipc_subscr *s, 237 struct tipc_subscr *s,
238 struct tipc_subscriber *subscriber) 238 int swap)
239{ 239{
240 struct tipc_net *tn = net_generic(net, tipc_net_id); 240 struct tipc_net *tn = net_generic(net, tipc_net_id);
241 struct tipc_subscription *sub; 241 struct tipc_subscription *sub;
242 u32 filter; 242 u32 filter = htohl(s->filter, swap);
243 int swap;
244
245 /* Determine subscriber's endianness */
246 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
247
248 /* Detect & process a subscription cancellation request */
249 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
250 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
251 tipc_subscrp_cancel(s, subscriber);
252 return NULL;
253 }
254 243
255 /* Refuse subscription if global limit exceeded */ 244 /* Refuse subscription if global limit exceeded */
256 if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) { 245 if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) {
@@ -268,7 +257,6 @@ static struct tipc_subscription *tipc_subscrp_create(struct net *net,
268 257
269 /* Initialize subscription object */ 258 /* Initialize subscription object */
270 sub->net = net; 259 sub->net = net;
271 filter = htohl(s->filter, swap);
272 if (((filter & TIPC_SUB_PORTS) && (filter & TIPC_SUB_SERVICE)) || 260 if (((filter & TIPC_SUB_PORTS) && (filter & TIPC_SUB_SERVICE)) ||
273 (htohl(s->seq.lower, swap) > htohl(s->seq.upper, swap))) { 261 (htohl(s->seq.lower, swap) > htohl(s->seq.upper, swap))) {
274 pr_warn("Subscription rejected, illegal request\n"); 262 pr_warn("Subscription rejected, illegal request\n");
@@ -284,13 +272,13 @@ static struct tipc_subscription *tipc_subscrp_create(struct net *net,
284} 272}
285 273
286static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s, 274static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s,
287 struct tipc_subscriber *subscriber) 275 struct tipc_subscriber *subscriber, int swap)
288{ 276{
289 struct tipc_net *tn = net_generic(net, tipc_net_id); 277 struct tipc_net *tn = net_generic(net, tipc_net_id);
290 struct tipc_subscription *sub = NULL; 278 struct tipc_subscription *sub = NULL;
291 u32 timeout; 279 u32 timeout;
292 280
293 sub = tipc_subscrp_create(net, s, subscriber); 281 sub = tipc_subscrp_create(net, s, swap);
294 if (!sub) 282 if (!sub)
295 return tipc_conn_terminate(tn->topsrv, subscriber->conid); 283 return tipc_conn_terminate(tn->topsrv, subscriber->conid);
296 284
@@ -299,7 +287,7 @@ static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s,
299 spin_unlock_bh(&subscriber->lock); 287 spin_unlock_bh(&subscriber->lock);
300 288
301 sub->subscriber = subscriber; 289 sub->subscriber = subscriber;
302 timeout = htohl(sub->evt.s.timeout, sub->swap); 290 timeout = htohl(sub->evt.s.timeout, swap);
303 if (!mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout))) 291 if (!mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout)))
304 tipc_subscrb_get(subscriber); 292 tipc_subscrb_get(subscriber);
305 tipc_nametbl_subscribe(sub); 293 tipc_nametbl_subscribe(sub);
@@ -316,8 +304,20 @@ static void tipc_subscrb_rcv_cb(struct net *net, int conid,
316 struct sockaddr_tipc *addr, void *usr_data, 304 struct sockaddr_tipc *addr, void *usr_data,
317 void *buf, size_t len) 305 void *buf, size_t len)
318{ 306{
319 tipc_subscrp_subscribe(net, (struct tipc_subscr *)buf, 307 struct tipc_subscriber *subscriber = usr_data;
320 (struct tipc_subscriber *)usr_data); 308 struct tipc_subscr *s = (struct tipc_subscr *)buf;
309 int swap;
310
311 /* Determine subscriber's endianness */
312 swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE));
313
314 /* Detect & process a subscription cancellation request */
315 if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
316 s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
317 return tipc_subscrp_cancel(s, subscriber);
318 }
319
320 tipc_subscrp_subscribe(net, s, subscriber, swap);
321} 321}
322 322
323/* Handle one request to establish a new subscriber */ 323/* Handle one request to establish a new subscriber */