aboutsummaryrefslogtreecommitdiffstats
path: root/net/tipc/msg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/tipc/msg.c')
-rw-r--r--net/tipc/msg.c130
1 files changed, 92 insertions, 38 deletions
diff --git a/net/tipc/msg.c b/net/tipc/msg.c
index b6eb90cd3ef7..c3e96e815418 100644
--- a/net/tipc/msg.c
+++ b/net/tipc/msg.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * net/tipc/msg.c: TIPC message header routines 2 * net/tipc/msg.c: TIPC message header routines
3 * 3 *
4 * Copyright (c) 2000-2006, 2014, Ericsson AB 4 * Copyright (c) 2000-2006, 2014-2015, Ericsson AB
5 * Copyright (c) 2005, 2010-2011, Wind River Systems 5 * Copyright (c) 2005, 2010-2011, Wind River Systems
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
@@ -165,6 +165,9 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
165 } 165 }
166 166
167 if (fragid == LAST_FRAGMENT) { 167 if (fragid == LAST_FRAGMENT) {
168 TIPC_SKB_CB(head)->validated = false;
169 if (unlikely(!tipc_msg_validate(head)))
170 goto err;
168 *buf = head; 171 *buf = head;
169 TIPC_SKB_CB(head)->tail = NULL; 172 TIPC_SKB_CB(head)->tail = NULL;
170 *headbuf = NULL; 173 *headbuf = NULL;
@@ -172,7 +175,6 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf)
172 } 175 }
173 *buf = NULL; 176 *buf = NULL;
174 return 0; 177 return 0;
175
176err: 178err:
177 pr_warn_ratelimited("Unable to build fragment list\n"); 179 pr_warn_ratelimited("Unable to build fragment list\n");
178 kfree_skb(*buf); 180 kfree_skb(*buf);
@@ -181,6 +183,48 @@ err:
181 return 0; 183 return 0;
182} 184}
183 185
186/* tipc_msg_validate - validate basic format of received message
187 *
188 * This routine ensures a TIPC message has an acceptable header, and at least
189 * as much data as the header indicates it should. The routine also ensures
190 * that the entire message header is stored in the main fragment of the message
191 * buffer, to simplify future access to message header fields.
192 *
193 * Note: Having extra info present in the message header or data areas is OK.
194 * TIPC will ignore the excess, under the assumption that it is optional info
195 * introduced by a later release of the protocol.
196 */
197bool tipc_msg_validate(struct sk_buff *skb)
198{
199 struct tipc_msg *msg;
200 int msz, hsz;
201
202 if (unlikely(TIPC_SKB_CB(skb)->validated))
203 return true;
204 if (unlikely(!pskb_may_pull(skb, MIN_H_SIZE)))
205 return false;
206
207 hsz = msg_hdr_sz(buf_msg(skb));
208 if (unlikely(hsz < MIN_H_SIZE) || (hsz > MAX_H_SIZE))
209 return false;
210 if (unlikely(!pskb_may_pull(skb, hsz)))
211 return false;
212
213 msg = buf_msg(skb);
214 if (unlikely(msg_version(msg) != TIPC_VERSION))
215 return false;
216
217 msz = msg_size(msg);
218 if (unlikely(msz < hsz))
219 return false;
220 if (unlikely((msz - hsz) > TIPC_MAX_USER_MSG_SIZE))
221 return false;
222 if (unlikely(skb->len < msz))
223 return false;
224
225 TIPC_SKB_CB(skb)->validated = true;
226 return true;
227}
184 228
185/** 229/**
186 * tipc_msg_build - create buffer chain containing specified header and data 230 * tipc_msg_build - create buffer chain containing specified header and data
@@ -228,6 +272,7 @@ int tipc_msg_build(struct tipc_msg *mhdr, struct msghdr *m,
228 FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(mhdr)); 272 FIRST_FRAGMENT, INT_H_SIZE, msg_destnode(mhdr));
229 msg_set_size(&pkthdr, pktmax); 273 msg_set_size(&pkthdr, pktmax);
230 msg_set_fragm_no(&pkthdr, pktno); 274 msg_set_fragm_no(&pkthdr, pktno);
275 msg_set_importance(&pkthdr, msg_importance(mhdr));
231 276
232 /* Prepare first fragment */ 277 /* Prepare first fragment */
233 skb = tipc_buf_acquire(pktmax); 278 skb = tipc_buf_acquire(pktmax);
@@ -286,33 +331,36 @@ error:
286 331
287/** 332/**
288 * tipc_msg_bundle(): Append contents of a buffer to tail of an existing one 333 * tipc_msg_bundle(): Append contents of a buffer to tail of an existing one
289 * @list: the buffer chain of the existing buffer ("bundle") 334 * @bskb: the buffer to append to ("bundle")
290 * @skb: buffer to be appended 335 * @skb: buffer to be appended
291 * @mtu: max allowable size for the bundle buffer 336 * @mtu: max allowable size for the bundle buffer
292 * Consumes buffer if successful 337 * Consumes buffer if successful
293 * Returns true if bundling could be performed, otherwise false 338 * Returns true if bundling could be performed, otherwise false
294 */ 339 */
295bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu) 340bool tipc_msg_bundle(struct sk_buff *bskb, struct sk_buff *skb, u32 mtu)
296{ 341{
297 struct sk_buff *bskb = skb_peek_tail(list); 342 struct tipc_msg *bmsg;
298 struct tipc_msg *bmsg = buf_msg(bskb);
299 struct tipc_msg *msg = buf_msg(skb); 343 struct tipc_msg *msg = buf_msg(skb);
300 unsigned int bsz = msg_size(bmsg); 344 unsigned int bsz;
301 unsigned int msz = msg_size(msg); 345 unsigned int msz = msg_size(msg);
302 u32 start = align(bsz); 346 u32 start, pad;
303 u32 max = mtu - INT_H_SIZE; 347 u32 max = mtu - INT_H_SIZE;
304 u32 pad = start - bsz;
305 348
306 if (likely(msg_user(msg) == MSG_FRAGMENTER)) 349 if (likely(msg_user(msg) == MSG_FRAGMENTER))
307 return false; 350 return false;
308 if (unlikely(msg_user(msg) == CHANGEOVER_PROTOCOL)) 351 if (!bskb)
352 return false;
353 bmsg = buf_msg(bskb);
354 bsz = msg_size(bmsg);
355 start = align(bsz);
356 pad = start - bsz;
357
358 if (unlikely(msg_user(msg) == TUNNEL_PROTOCOL))
309 return false; 359 return false;
310 if (unlikely(msg_user(msg) == BCAST_PROTOCOL)) 360 if (unlikely(msg_user(msg) == BCAST_PROTOCOL))
311 return false; 361 return false;
312 if (likely(msg_user(bmsg) != MSG_BUNDLER)) 362 if (likely(msg_user(bmsg) != MSG_BUNDLER))
313 return false; 363 return false;
314 if (likely(!TIPC_SKB_CB(bskb)->bundling))
315 return false;
316 if (unlikely(skb_tailroom(bskb) < (pad + msz))) 364 if (unlikely(skb_tailroom(bskb) < (pad + msz)))
317 return false; 365 return false;
318 if (unlikely(max < (start + msz))) 366 if (unlikely(max < (start + msz)))
@@ -328,34 +376,40 @@ bool tipc_msg_bundle(struct sk_buff_head *list, struct sk_buff *skb, u32 mtu)
328 376
329/** 377/**
330 * tipc_msg_extract(): extract bundled inner packet from buffer 378 * tipc_msg_extract(): extract bundled inner packet from buffer
331 * @skb: linear outer buffer, to be extracted from. 379 * @skb: buffer to be extracted from.
332 * @iskb: extracted inner buffer, to be returned 380 * @iskb: extracted inner buffer, to be returned
333 * @pos: position of msg to be extracted. Returns with pointer of next msg 381 * @pos: position in outer message of msg to be extracted.
382 * Returns position of next msg
334 * Consumes outer buffer when last packet extracted 383 * Consumes outer buffer when last packet extracted
335 * Returns true when when there is an extracted buffer, otherwise false 384 * Returns true when when there is an extracted buffer, otherwise false
336 */ 385 */
337bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos) 386bool tipc_msg_extract(struct sk_buff *skb, struct sk_buff **iskb, int *pos)
338{ 387{
339 struct tipc_msg *msg = buf_msg(skb); 388 struct tipc_msg *msg;
340 int imsz; 389 int imsz, offset;
341 struct tipc_msg *imsg = (struct tipc_msg *)(msg_data(msg) + *pos);
342 390
343 /* Is there space left for shortest possible message? */ 391 *iskb = NULL;
344 if (*pos > (msg_data_sz(msg) - SHORT_H_SIZE)) 392 if (unlikely(skb_linearize(skb)))
393 goto none;
394
395 msg = buf_msg(skb);
396 offset = msg_hdr_sz(msg) + *pos;
397 if (unlikely(offset > (msg_size(msg) - MIN_H_SIZE)))
345 goto none; 398 goto none;
346 imsz = msg_size(imsg);
347 399
348 /* Is there space left for current message ? */ 400 *iskb = skb_clone(skb, GFP_ATOMIC);
349 if ((*pos + imsz) > msg_data_sz(msg)) 401 if (unlikely(!*iskb))
350 goto none; 402 goto none;
351 *iskb = tipc_buf_acquire(imsz); 403 skb_pull(*iskb, offset);
352 if (!*iskb) 404 imsz = msg_size(buf_msg(*iskb));
405 skb_trim(*iskb, imsz);
406 if (unlikely(!tipc_msg_validate(*iskb)))
353 goto none; 407 goto none;
354 skb_copy_to_linear_data(*iskb, imsg, imsz);
355 *pos += align(imsz); 408 *pos += align(imsz);
356 return true; 409 return true;
357none: 410none:
358 kfree_skb(skb); 411 kfree_skb(skb);
412 kfree_skb(*iskb);
359 *iskb = NULL; 413 *iskb = NULL;
360 return false; 414 return false;
361} 415}
@@ -369,18 +423,17 @@ none:
369 * Replaces buffer if successful 423 * Replaces buffer if successful
370 * Returns true if success, otherwise false 424 * Returns true if success, otherwise false
371 */ 425 */
372bool tipc_msg_make_bundle(struct sk_buff_head *list, 426bool tipc_msg_make_bundle(struct sk_buff **skb, u32 mtu, u32 dnode)
373 struct sk_buff *skb, u32 mtu, u32 dnode)
374{ 427{
375 struct sk_buff *bskb; 428 struct sk_buff *bskb;
376 struct tipc_msg *bmsg; 429 struct tipc_msg *bmsg;
377 struct tipc_msg *msg = buf_msg(skb); 430 struct tipc_msg *msg = buf_msg(*skb);
378 u32 msz = msg_size(msg); 431 u32 msz = msg_size(msg);
379 u32 max = mtu - INT_H_SIZE; 432 u32 max = mtu - INT_H_SIZE;
380 433
381 if (msg_user(msg) == MSG_FRAGMENTER) 434 if (msg_user(msg) == MSG_FRAGMENTER)
382 return false; 435 return false;
383 if (msg_user(msg) == CHANGEOVER_PROTOCOL) 436 if (msg_user(msg) == TUNNEL_PROTOCOL)
384 return false; 437 return false;
385 if (msg_user(msg) == BCAST_PROTOCOL) 438 if (msg_user(msg) == BCAST_PROTOCOL)
386 return false; 439 return false;
@@ -398,9 +451,9 @@ bool tipc_msg_make_bundle(struct sk_buff_head *list,
398 msg_set_seqno(bmsg, msg_seqno(msg)); 451 msg_set_seqno(bmsg, msg_seqno(msg));
399 msg_set_ack(bmsg, msg_ack(msg)); 452 msg_set_ack(bmsg, msg_ack(msg));
400 msg_set_bcast_ack(bmsg, msg_bcast_ack(msg)); 453 msg_set_bcast_ack(bmsg, msg_bcast_ack(msg));
401 TIPC_SKB_CB(bskb)->bundling = true; 454 tipc_msg_bundle(bskb, *skb, mtu);
402 __skb_queue_tail(list, bskb); 455 *skb = bskb;
403 return tipc_msg_bundle(list, skb, mtu); 456 return true;
404} 457}
405 458
406/** 459/**
@@ -415,21 +468,17 @@ bool tipc_msg_reverse(u32 own_addr, struct sk_buff *buf, u32 *dnode,
415 int err) 468 int err)
416{ 469{
417 struct tipc_msg *msg = buf_msg(buf); 470 struct tipc_msg *msg = buf_msg(buf);
418 uint imp = msg_importance(msg);
419 struct tipc_msg ohdr; 471 struct tipc_msg ohdr;
420 uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE); 472 uint rdsz = min_t(uint, msg_data_sz(msg), MAX_FORWARD_SIZE);
421 473
422 if (skb_linearize(buf)) 474 if (skb_linearize(buf))
423 goto exit; 475 goto exit;
476 msg = buf_msg(buf);
424 if (msg_dest_droppable(msg)) 477 if (msg_dest_droppable(msg))
425 goto exit; 478 goto exit;
426 if (msg_errcode(msg)) 479 if (msg_errcode(msg))
427 goto exit; 480 goto exit;
428
429 memcpy(&ohdr, msg, msg_hdr_sz(msg)); 481 memcpy(&ohdr, msg, msg_hdr_sz(msg));
430 imp = min_t(uint, imp + 1, TIPC_CRITICAL_IMPORTANCE);
431 if (msg_isdata(msg))
432 msg_set_importance(msg, imp);
433 msg_set_errcode(msg, err); 482 msg_set_errcode(msg, err);
434 msg_set_origport(msg, msg_destport(&ohdr)); 483 msg_set_origport(msg, msg_destport(&ohdr));
435 msg_set_destport(msg, msg_origport(&ohdr)); 484 msg_set_destport(msg, msg_origport(&ohdr));
@@ -462,15 +511,18 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb,
462{ 511{
463 struct tipc_msg *msg = buf_msg(skb); 512 struct tipc_msg *msg = buf_msg(skb);
464 u32 dport; 513 u32 dport;
514 u32 own_addr = tipc_own_addr(net);
465 515
466 if (!msg_isdata(msg)) 516 if (!msg_isdata(msg))
467 return false; 517 return false;
468 if (!msg_named(msg)) 518 if (!msg_named(msg))
469 return false; 519 return false;
520 if (msg_errcode(msg))
521 return false;
470 *err = -TIPC_ERR_NO_NAME; 522 *err = -TIPC_ERR_NO_NAME;
471 if (skb_linearize(skb)) 523 if (skb_linearize(skb))
472 return false; 524 return false;
473 if (msg_reroute_cnt(msg) > 0) 525 if (msg_reroute_cnt(msg))
474 return false; 526 return false;
475 *dnode = addr_domain(net, msg_lookup_scope(msg)); 527 *dnode = addr_domain(net, msg_lookup_scope(msg));
476 dport = tipc_nametbl_translate(net, msg_nametype(msg), 528 dport = tipc_nametbl_translate(net, msg_nametype(msg),
@@ -478,6 +530,8 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb,
478 if (!dport) 530 if (!dport)
479 return false; 531 return false;
480 msg_incr_reroute_cnt(msg); 532 msg_incr_reroute_cnt(msg);
533 if (*dnode != own_addr)
534 msg_set_prevnode(msg, own_addr);
481 msg_set_destnode(msg, *dnode); 535 msg_set_destnode(msg, *dnode);
482 msg_set_destport(msg, dport); 536 msg_set_destport(msg, dport);
483 *err = TIPC_OK; 537 *err = TIPC_OK;