Acked-by: Jon Maloy <[email protected]>

-----Original Message-----
From: Tung Nguyen [mailto:[email protected]] 
Sent: Friday, April 27, 2018 12:19 AM
To: [email protected]; Jon Maloy <[email protected]>; 
[email protected]; [email protected]
Subject: [PATCH v1 1/1] tipc: remove skb_clone() in function tipc_msg_extract()

Function tipc_msg_extract() is using skb_clone() to clone inner messages from 
bundle message. Although it is safe to use this method, it has an undesired 
effect that each clone inherits the true-size of the original buffer. As a 
result, the clone almost always has to be copied by function 
tipc_msg_validate().

This commit fixes it by coping each inner message to a separately-allocated 
message buffer before being returned to caller.

Signed-off-by: Tung Nguyen <[email protected]>
---
 net/tipc/msg.c | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/net/tipc/msg.c b/net/tipc/msg.c index b6c45dc..b59c0e6 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)
  */
 bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos)  {
-       struct tipc_msg *msg;
-       int imsz, offset;
+       struct tipc_msg *hdr, *ihdr;
+       int imsz;
 
        *iskb = NULL;
        if (unlikely(skb_linearize(skb)))
                goto none;
 
-       msg = buf_msg(skb);
-       offset = msg_hdr_sz(msg) + *pos;
-       if (unlikely(offset > (msg_size(msg) - MIN_H_SIZE)))
+       hdr = buf_msg(skb);
+       if (unlikely(*pos > (msg_data_sz(hdr) - MIN_H_SIZE)))
                goto none;
 
-       *iskb = skb_clone(skb, GFP_ATOMIC);
-       if (unlikely(!*iskb))
+       ihdr = (struct tipc_msg *)(msg_data(hdr) + *pos);
+       imsz = msg_size(ihdr);
+       
+       if ((*pos + imsz) > msg_data_sz(hdr))
                goto none;
-       skb_pull(*iskb, offset);
-       imsz = msg_size(buf_msg(*iskb));
-       skb_trim(*iskb, imsz);
+
+       *iskb = tipc_buf_acquire(imsz, GFP_ATOMIC);
+       if (!*iskb)
+               goto none;
+
+       skb_copy_to_linear_data(*iskb, ihdr, imsz);
        if (unlikely(!tipc_msg_validate(iskb)))
                goto none;
+
        *pos += align(imsz);
        return true;
 none:
@@ -531,12 +536,6 @@ bool tipc_msg_reverse(u32 own_node,  struct sk_buff **skb, 
int err)
                msg_set_hdr_sz(hdr, BASIC_H_SIZE);
        }
 
-       if (skb_cloned(_skb) &&
-           pskb_expand_head(_skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
-               goto exit;
-
-       /* reassign after skb header modifications */
-       hdr = buf_msg(_skb);
        /* Now reverse the concerned fields */
        msg_set_errcode(hdr, err);
        msg_set_non_seq(hdr, 0);
@@ -595,10 +594,6 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff 
*skb, int *err)
        if (!skb_cloned(skb))
                return true;
 
-       /* Unclone buffer in case it was bundled */
-       if (pskb_expand_head(skb, BUF_HEADROOM, BUF_TAILROOM, GFP_ATOMIC))
-               return false;
-
        return true;
 }
 
--
2.8.3


------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
tipc-discussion mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/tipc-discussion

Reply via email to