aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc')
-rw-r--r--net/tipc/msg.c35
1 files changed, 15 insertions, 20 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index b6c45dccba3d..b61891054709 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -416,26 +416,31 @@ bool tipc_msg_bundle(struct sk_buff *skb, struct tipc_msg *msg, u32 mtu)
416 */ 416 */
417bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos) 417bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos)
418{ 418{
419 struct tipc_msg *msg; 419 struct tipc_msg *hdr, *ihdr;
420 int imsz, offset; 420 int imsz;
421 421
422 *iskb = NULL; 422 *iskb = NULL;
423 if (unlikely(skb_linearize(skb))) 423 if (unlikely(skb_linearize(skb)))
424 goto none; 424 goto none;
425 425
426 msg = buf_msg(skb); 426 hdr = buf_msg(skb);
427 offset = msg_hdr_sz(msg) + *pos; 427 if (unlikely(*pos > (msg_data_sz(hdr) - MIN_H_SIZE)))
428 if (unlikely(offset > (msg_size(msg) - MIN_H_SIZE)))
429 goto none; 428 goto none;
430 429
431 *iskb = skb_clone(skb, GFP_ATOMIC); 430 ihdr = (struct tipc_msg *)(msg_data(hdr) + *pos);
432 if (unlikely(!*iskb)) 431 imsz = msg_size(ihdr);
432
433 if ((*pos + imsz) > msg_data_sz(hdr))
433 goto none; 434 goto none;
434 skb_pull(*iskb, offset); 435
435 imsz = msg_size(buf_msg(*iskb)); 436 *iskb = tipc_buf_acquire(imsz, GFP_ATOMIC);
436 skb_trim(*iskb, imsz); 437 if (!*iskb)
438 goto none;
439
440 skb_copy_to_linear_data(*iskb, ihdr, imsz);
437 if (unlikely(!tipc_msg_validate(iskb))) 441 if (unlikely(!tipc_msg_validate(iskb)))
438 goto none; 442 goto none;
443
439 *pos += align(imsz); 444 *pos += align(imsz);
440 return true; 445 return true;
441none: 446none:
@@ -531,12 +536,6 @@ bool tipc_msg_reverse(u32 own_node, struct sk_buff **skb, int err)
531 msg_set_hdr_sz(hdr, BASIC_H_SIZE); 536 msg_set_hdr_sz(hdr, BASIC_H_SIZE);
532 } 537 }
533 538
534 if (skb_cloned(_skb) &&
535 pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
536 goto exit;
537
538 /* reassign after skb header modifications */
539 hdr = buf_msg(_skb);
540 /* Now reverse the concerned fields */ 539 /* Now reverse the concerned fields */
541 msg_set_errcode(hdr, err); 540 msg_set_errcode(hdr, err);
542 msg_set_non_seq(hdr, 0); 541 msg_set_non_seq(hdr, 0);
@@ -595,10 +594,6 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err)
595 if (!skb_cloned(skb)) 594 if (!skb_cloned(skb))
596 return true; 595 return true;
597 596
598 /* Unclone buffer in case it was bundled */
599 if (pskb_expand_head(skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
600 return false;
601
602 return true; 597 return true;
603} 598}
604 599