diff options
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r-- | net/tipc/msg.c | 22 |
1 files changed, 9 insertions, 13 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c index ced60e2fc4f7..1e76d91e5691 100644 --- a/net/tipc/msg.c +++ b/net/tipc/msg.c | |||
@@ -76,10 +76,11 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, | |||
76 | u32 num_sect, unsigned int total_len, int max_size, | 76 | u32 num_sect, unsigned int total_len, int max_size, |
77 | struct sk_buff **buf) | 77 | struct sk_buff **buf) |
78 | { | 78 | { |
79 | int dsz, sz, hsz, pos, res, cnt; | 79 | int dsz, sz, hsz; |
80 | unsigned char *to; | ||
80 | 81 | ||
81 | dsz = total_len; | 82 | dsz = total_len; |
82 | pos = hsz = msg_hdr_sz(hdr); | 83 | hsz = msg_hdr_sz(hdr); |
83 | sz = hsz + dsz; | 84 | sz = hsz + dsz; |
84 | msg_set_size(hdr, sz); | 85 | msg_set_size(hdr, sz); |
85 | if (unlikely(sz > max_size)) { | 86 | if (unlikely(sz > max_size)) { |
@@ -91,16 +92,11 @@ int tipc_msg_build(struct tipc_msg *hdr, struct iovec const *msg_sect, | |||
91 | if (!(*buf)) | 92 | if (!(*buf)) |
92 | return -ENOMEM; | 93 | return -ENOMEM; |
93 | skb_copy_to_linear_data(*buf, hdr, hsz); | 94 | skb_copy_to_linear_data(*buf, hdr, hsz); |
94 | for (res = 1, cnt = 0; res && (cnt < num_sect); cnt++) { | 95 | to = (*buf)->data + hsz; |
95 | skb_copy_to_linear_data_offset(*buf, pos, | 96 | if (total_len && memcpy_fromiovecend(to, msg_sect, 0, dsz)) { |
96 | msg_sect[cnt].iov_base, | 97 | kfree_skb(*buf); |
97 | msg_sect[cnt].iov_len); | 98 | *buf = NULL; |
98 | pos += msg_sect[cnt].iov_len; | 99 | return -EFAULT; |
99 | } | 100 | } |
100 | if (likely(res)) | 101 | return dsz; |
101 | return dsz; | ||
102 | |||
103 | kfree_skb(*buf); | ||
104 | *buf = NULL; | ||
105 | return -EFAULT; | ||
106 | } | 102 | } |