@@ -378,6 +378,7 @@ static void mctp_skb_set_flow(struct sk_buff *skb, struct mctp_sk_key *key) {}
378
378
static void mctp_flow_prepare_output (struct sk_buff * skb , struct mctp_dev * dev ) {}
379
379
#endif
380
380
381
+ /* takes ownership of skb, both in success and failure cases */
381
382
static int mctp_frag_queue (struct mctp_sk_key * key , struct sk_buff * skb )
382
383
{
383
384
struct mctp_hdr * hdr = mctp_hdr (skb );
@@ -387,8 +388,10 @@ static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
387
388
& MCTP_HDR_SEQ_MASK ;
388
389
389
390
if (!key -> reasm_head ) {
390
- /* Since we're manipulating the shared frag_list, ensure it isn't
391
- * shared with any other SKBs.
391
+ /* Since we're manipulating the shared frag_list, ensure it
392
+ * isn't shared with any other SKBs. In the cloned case,
393
+ * this will free the skb; callers can no longer access it
394
+ * safely.
392
395
*/
393
396
key -> reasm_head = skb_unshare (skb , GFP_ATOMIC );
394
397
if (!key -> reasm_head )
@@ -402,10 +405,10 @@ static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
402
405
exp_seq = (key -> last_seq + 1 ) & MCTP_HDR_SEQ_MASK ;
403
406
404
407
if (this_seq != exp_seq )
405
- return - EINVAL ;
408
+ goto err_free ;
406
409
407
410
if (key -> reasm_head -> len + skb -> len > mctp_message_maxlen )
408
- return - EINVAL ;
411
+ goto err_free ;
409
412
410
413
skb -> next = NULL ;
411
414
skb -> sk = NULL ;
@@ -419,6 +422,10 @@ static int mctp_frag_queue(struct mctp_sk_key *key, struct sk_buff *skb)
419
422
key -> reasm_head -> truesize += skb -> truesize ;
420
423
421
424
return 0 ;
425
+
426
+ err_free :
427
+ kfree_skb (skb );
428
+ return - EINVAL ;
422
429
}
423
430
424
431
static int mctp_dst_input (struct mctp_dst * dst , struct sk_buff * skb )
@@ -532,18 +539,16 @@ static int mctp_dst_input(struct mctp_dst *dst, struct sk_buff *skb)
532
539
* key isn't observable yet
533
540
*/
534
541
mctp_frag_queue (key , skb );
542
+ skb = NULL ;
535
543
536
544
/* if the key_add fails, we've raced with another
537
545
* SOM packet with the same src, dest and tag. There's
538
546
* no way to distinguish future packets, so all we
539
- * can do is drop; we'll free the skb on exit from
540
- * this function.
547
+ * can do is drop.
541
548
*/
542
549
rc = mctp_key_add (key , msk );
543
- if (!rc ) {
550
+ if (!rc )
544
551
trace_mctp_key_acquire (key );
545
- skb = NULL ;
546
- }
547
552
548
553
/* we don't need to release key->lock on exit, so
549
554
* clean up here and suppress the unlock via
@@ -561,8 +566,7 @@ static int mctp_dst_input(struct mctp_dst *dst, struct sk_buff *skb)
561
566
key = NULL ;
562
567
} else {
563
568
rc = mctp_frag_queue (key , skb );
564
- if (!rc )
565
- skb = NULL ;
569
+ skb = NULL ;
566
570
}
567
571
}
568
572
@@ -572,17 +576,16 @@ static int mctp_dst_input(struct mctp_dst *dst, struct sk_buff *skb)
572
576
*/
573
577
574
578
/* we need to be continuing an existing reassembly... */
575
- if (!key -> reasm_head )
579
+ if (!key -> reasm_head ) {
576
580
rc = - EINVAL ;
577
- else
581
+ } else {
578
582
rc = mctp_frag_queue (key , skb );
583
+ skb = NULL ;
584
+ }
579
585
580
586
if (rc )
581
587
goto out_unlock ;
582
588
583
- /* we've queued; the queue owns the skb now */
584
- skb = NULL ;
585
-
586
589
/* end of message? deliver to socket, and we're done with
587
590
* the reassembly/response key
588
591
*/
0 commit comments