Skip to content

Commit da703fe

Browse files
committed
Merge tag 'xsa432-6.5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip
Pull xen netback buffer overflow fix from Juergen Gross: "The fix for XSA-423 added logic to Linux'es netback driver to deal with a frontend splitting a packet in a way such that not all of the headers would come in one piece. Unfortunately the logic introduced there didn't account for the extreme case of the entire packet being split into as many pieces as permitted by the protocol, yet still being smaller than the area that's specially dealt with to keep all (possible) headers together. Such an unusual packet would therefore trigger a buffer overrun in the driver" * tag 'xsa432-6.5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/xen/tip: xen/netback: Fix buffer overrun triggered by unusual packet
2 parents 64094e7 + 534fc31 commit da703fe

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

drivers/net/xen-netback/netback.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
396396
struct gnttab_map_grant_ref *gop = queue->tx_map_ops + *map_ops;
397397
struct xen_netif_tx_request *txp = first;
398398

399-
nr_slots = shinfo->nr_frags + 1;
399+
nr_slots = shinfo->nr_frags + frag_overflow + 1;
400400

401401
copy_count(skb) = 0;
402402
XENVIF_TX_CB(skb)->split_mask = 0;
@@ -462,8 +462,8 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
462462
}
463463
}
464464

465-
for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
466-
shinfo->nr_frags++, gop++) {
465+
for (shinfo->nr_frags = 0; nr_slots > 0 && shinfo->nr_frags < MAX_SKB_FRAGS;
466+
shinfo->nr_frags++, gop++, nr_slots--) {
467467
index = pending_index(queue->pending_cons++);
468468
pending_idx = queue->pending_ring[index];
469469
xenvif_tx_create_map_op(queue, pending_idx, txp,
@@ -476,12 +476,12 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
476476
txp++;
477477
}
478478

479-
if (frag_overflow) {
479+
if (nr_slots > 0) {
480480

481481
shinfo = skb_shinfo(nskb);
482482
frags = shinfo->frags;
483483

484-
for (shinfo->nr_frags = 0; shinfo->nr_frags < frag_overflow;
484+
for (shinfo->nr_frags = 0; shinfo->nr_frags < nr_slots;
485485
shinfo->nr_frags++, txp++, gop++) {
486486
index = pending_index(queue->pending_cons++);
487487
pending_idx = queue->pending_ring[index];
@@ -492,6 +492,11 @@ static void xenvif_get_requests(struct xenvif_queue *queue,
492492
}
493493

494494
skb_shinfo(skb)->frag_list = nskb;
495+
} else if (nskb) {
496+
/* A frag_list skb was allocated but it is no longer needed
497+
* because enough slots were converted to copy ops above.
498+
*/
499+
kfree_skb(nskb);
495500
}
496501

497502
(*copy_ops) = cop - queue->tx_copy_ops;

0 commit comments

Comments
 (0)