git: 32d1d7fee613 - stable/13 - LinuxKPI: skbuff: fix skb_queue_splice_init()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 27 Mar 2022 20:14:04 UTC
The branch stable/13 has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=32d1d7fee61328e65ae944836d1027335ccb979c commit 32d1d7fee61328e65ae944836d1027335ccb979c Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2022-03-23 17:05:43 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2022-03-27 18:08:53 +0000 LinuxKPI: skbuff: fix skb_queue_splice_init() In skb_queue_splice_init() we set a next value and then used that new value to further update the remaining linking rather than the original value. Introduce another temporary variable 'n' to hold the original value and use that. While here rename q and h to from and to as otherwise it was too confusing to read. Also initialize skb->prev and skb->next to point to skb itself if for nothing else at least to aid debugging. Reported by: phk (panic in iwl_txq_reclaim) Sponsored by: The FreeBSD Foundation (cherry picked from commit 6a8973c3324c0c6c270ae4ad371e50c0ec5761da) --- sys/compat/linuxkpi/common/include/linux/skbuff.h | 25 ++++++++++++----------- sys/compat/linuxkpi/common/src/linux_skbuff.c | 2 ++ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/sys/compat/linuxkpi/common/include/linux/skbuff.h b/sys/compat/linuxkpi/common/include/linux/skbuff.h index be93032c7561..21ea7ee560e2 100644 --- a/sys/compat/linuxkpi/common/include/linux/skbuff.h +++ b/sys/compat/linuxkpi/common/include/linux/skbuff.h @@ -762,26 +762,27 @@ skb_mark_not_on_list(struct sk_buff *skb) } static inline void -skb_queue_splice_init(struct sk_buff_head *q, struct sk_buff_head *h) +skb_queue_splice_init(struct sk_buff_head *from, struct sk_buff_head *to) { - struct sk_buff *b, *e; + struct sk_buff *b, *e, *n; - SKB_TRACE2(q, h); + SKB_TRACE2(from, to); - if (skb_queue_empty(q)) + if (skb_queue_empty(from)) return; /* XXX do we need a barrier around this? */ - b = q->next; - e = q->prev; + b = from->next; + e = from->prev; + n = to->next; - b->prev = (struct sk_buff *)h; - h->next = b; - e->next = h->next; - h->next->prev = e; + b->prev = (struct sk_buff *)to; + to->next = b; + e->next = n; + n->prev = e; - h->qlen += q->qlen; - __skb_queue_head_init(q); + to->qlen += from->qlen; + __skb_queue_head_init(from); } static inline void diff --git a/sys/compat/linuxkpi/common/src/linux_skbuff.c b/sys/compat/linuxkpi/common/src/linux_skbuff.c index 0a4974d74d9d..efb97fa2f126 100644 --- a/sys/compat/linuxkpi/common/src/linux_skbuff.c +++ b/sys/compat/linuxkpi/common/src/linux_skbuff.c @@ -86,6 +86,8 @@ linuxkpi_alloc_skb(size_t size, gfp_t gfp) skb->head = skb->data = skb->tail = (uint8_t *)(skb+1); skb->end = skb->head + size; + skb->prev = skb->next = skb; + skb->shinfo = (struct skb_shared_info *)(skb->end); SKB_TRACE_FMT(skb, "data %p size %zu", skb->data, size);