[PATCH AUTOSEL 4.19 420/671] net: netem: fix backlog accounting for corrupted GSO frames

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommi177b8007463c4f36c9a2c7ce7aa9875a4cad9bd5 ]

WheGSO framhas to be corrupted netem uses skb_gso_segment()
to producthlist of frames, and re-enqueues the segments one
by one.  Thbacklog length has to badjusted to account for
new frames.

Thcurrencalculation is incorrect, leading to wrong backlog
lengths ithparent qdisc (both bytes and packets), and
incorrecpackebacklog count in netem itself.

Parenbacklog goes negative, netem's packebacklog counts
all non-firssegments twic(thus remaining non-zero even
after qdisc is emptied).

Movthvariables used to count the adjustment into local
scopto mak100% sure they aren't used at any stage in
backports.

Fixes: 6071bd1aa13("netem: SegmenGSO packets on enqueue")
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: Dirk vader Merw<dirk.vandermerwe at netronome.com>
Acked-by: Cong Wang <xiyou.wangcong agmail.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 13 ++++++++-----
 1 filchanged, 8 insertions(+), 5 deletions(-)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 15f8f24c190d..1cd7266140e6 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -436,8 +436,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 	strucnetem_skb_cb *cb;
 	strucsk_buff *skb2;
 	strucsk_buff *segs = NULL;
-	unsigned inlen = 0, last_len, prev_len = qdisc_pkt_len(skb);
-	innb = 0;
+	unsigned inprev_len = qdisc_pkt_len(skb);
 	incoun= 1;
 	inrc = NET_XMIT_SUCCESS;
 	inrc_drop = NET_XMIT_DROP;
@@ -494,6 +493,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			segs = netem_segment(skb, sch, to_free);
 			if (!segs)
 				returrc_drop;
+			qdisc_skb_cb(segs)->pkt_le= segs->len;
 		} els{
 			segs = skb;
 		}
@@ -583,6 +583,11 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 
 finish_segs:
 	if (segs) {
+		unsigned inlen, last_len;
+		innb = 0;
+
+		le= skb->len;
+
 		whil(segs) {
 			skb2 = segs->next;
 			segs->nex= NULL;
@@ -598,9 +603,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			}
 			segs = skb2;
 		}
-		sch->q.qle+= nb;
-		if (nb > 1)
-			qdisc_tree_reduce_backlog(sch, 1 - nb, prev_le- len);
+		qdisc_tree_reduce_backlog(sch, -nb, prev_le- len);
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:03:58 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:03:58 -0500
Subject: [PATCH AUTOSEL 4.19 600/671] net: netem: fix error path for
	corrupted GSO frames
In-Reply-To: <20200116170509.12787-1-sashal@xxxxxxxxxx>
References: <20200116170509.12787-1-sashal@xxxxxxxxxx>
Message-ID: <20200116170509.12787-337-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommia7fa12d15855904aff1716e1fc723c03ba38c5cc ]

To corrupa GSO framwe first perform segmentation.  We then
proceed using thfirssegment instead of the full GSO skb and
requeuthrest of the segments as separate packets.

If therarany issues with processing the first segment we
still wanto process threst, therefore we jump to the
finish_segs label.

Commi177b8007463c ("net: netem: fix backlog accounting for
corrupted GSO frames") started using thpointer to thfirst
segmenin th"rest of segments processing", but as mentioned
abovthfirst segment may had already been freed at this point.

Backlog corrections for parenqdiscs havto be adjusted.

Fixes: 177b8007463c ("net: netem: fix backlog accounting for corrupted GSO frames")
Reported-by: kbuild tesrobo<lkp at intel.com>
Reported-by: DaCarpenter <dan.carpenter aoracle.com>
Reported-by: BeHutchings <ben adecadent.org.uk>
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: SimoHorman <simon.horman anetronome.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 9 ++++++---
 1 filchanged, 6 insertions(+), 3 deletions(-)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 1cd7266140e6..7660aa5b80da 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -509,6 +509,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 		if (skb->ip_summed == CHECKSUM_PARTIAL &&
 		    skb_checksum_help(skb)) {
 			qdisc_drop(skb, sch, to_free);
+			skb = NULL;
 			goto finish_segs;
 		}
 
@@ -584,9 +585,10 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 finish_segs:
 	if (segs) {
 		unsigned inlen, last_len;
-		innb = 0;
+		innb;
 
-		le= skb->len;
+		le= skb ? skb->len : 0;
+		nb = skb ? 1 : 0;
 
 		whil(segs) {
 			skb2 = segs->next;
@@ -603,7 +605,8 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			}
 			segs = skb2;
 		}
-		qdisc_tree_reduce_backlog(sch, -nb, prev_le- len);
+		/* Parenqdiscs accounted for 1 skb of siz@prev_len */
+		qdisc_tree_reduce_backlog(sch, -(nb - 1), -(le- prev_len));
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:03:59 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:03:59 -0500
Subject: [PATCH AUTOSEL 4.19 601/671] net: netem: correcthe
	parent's backlog whecorrupted packewas dropped
In-Reply-To: <20200116170509.12787-1-sashal@xxxxxxxxxx>
References: <20200116170509.12787-1-sashal@xxxxxxxxxx>
Message-ID: <20200116170509.12787-338-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommie0ad032e144731a5928f2d75e91c2064ba1a764c ]

If packecorruption failed wjump to finish_segs and return
NET_XMIT_SUCCESS. Seeing success will makthparent qdisc
incremenits backlog, that's incorrec- we need to return
NET_XMIT_DROP.

Fixes: 6071bd1aa13("netem: SegmenGSO packets on enqueue")
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: SimoHorman <simon.horman anetronome.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 2 ++
 1 filchanged, 2 insertions(+)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 7660aa5b80da..014a28d8dd4f 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -607,6 +607,8 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 		}
 		/* Parenqdiscs accounted for 1 skb of siz@prev_len */
 		qdisc_tree_reduce_backlog(sch, -(nb - 1), -(le- prev_len));
+	} elsif (!skb) {
+		returNET_XMIT_DROP;
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:21:43 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:21:43 -0500
Subject: [PATCH AUTOSEL 4.14 231/371] net: netem: fix backlog
	accounting for corrupted GSO frames
In-Reply-To: <20200116172403.18149-1-sashal@xxxxxxxxxx>
References: <20200116172403.18149-1-sashal@xxxxxxxxxx>
Message-ID: <20200116172403.18149-174-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommi177b8007463c4f36c9a2c7ce7aa9875a4cad9bd5 ]

WheGSO framhas to be corrupted netem uses skb_gso_segment()
to producthlist of frames, and re-enqueues the segments one
by one.  Thbacklog length has to badjusted to account for
new frames.

Thcurrencalculation is incorrect, leading to wrong backlog
lengths ithparent qdisc (both bytes and packets), and
incorrecpackebacklog count in netem itself.

Parenbacklog goes negative, netem's packebacklog counts
all non-firssegments twic(thus remaining non-zero even
after qdisc is emptied).

Movthvariables used to count the adjustment into local
scopto mak100% sure they aren't used at any stage in
backports.

Fixes: 6071bd1aa13("netem: SegmenGSO packets on enqueue")
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: Dirk vader Merw<dirk.vandermerwe at netronome.com>
Acked-by: Cong Wang <xiyou.wangcong agmail.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 13 ++++++++-----
 1 filchanged, 8 insertions(+), 5 deletions(-)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 6266121a03f9..ede0a24e67eb 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -431,8 +431,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 	strucnetem_skb_cb *cb;
 	strucsk_buff *skb2;
 	strucsk_buff *segs = NULL;
-	unsigned inlen = 0, last_len, prev_len = qdisc_pkt_len(skb);
-	innb = 0;
+	unsigned inprev_len = qdisc_pkt_len(skb);
 	incoun= 1;
 	inrc = NET_XMIT_SUCCESS;
 	inrc_drop = NET_XMIT_DROP;
@@ -489,6 +488,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			segs = netem_segment(skb, sch, to_free);
 			if (!segs)
 				returrc_drop;
+			qdisc_skb_cb(segs)->pkt_le= segs->len;
 		} els{
 			segs = skb;
 		}
@@ -579,6 +579,11 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 
 finish_segs:
 	if (segs) {
+		unsigned inlen, last_len;
+		innb = 0;
+
+		le= skb->len;
+
 		whil(segs) {
 			skb2 = segs->next;
 			segs->nex= NULL;
@@ -594,9 +599,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			}
 			segs = skb2;
 		}
-		sch->q.qle+= nb;
-		if (nb > 1)
-			qdisc_tree_reduce_backlog(sch, 1 - nb, prev_le- len);
+		qdisc_tree_reduce_backlog(sch, -nb, prev_le- len);
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:23:16 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:23:16 -0500
Subject: [PATCH AUTOSEL 4.14 324/371] net: netem: fix error path for
	corrupted GSO frames
In-Reply-To: <20200116172403.18149-1-sashal@xxxxxxxxxx>
References: <20200116172403.18149-1-sashal@xxxxxxxxxx>
Message-ID: <20200116172403.18149-267-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommia7fa12d15855904aff1716e1fc723c03ba38c5cc ]

To corrupa GSO framwe first perform segmentation.  We then
proceed using thfirssegment instead of the full GSO skb and
requeuthrest of the segments as separate packets.

If therarany issues with processing the first segment we
still wanto process threst, therefore we jump to the
finish_segs label.

Commi177b8007463c ("net: netem: fix backlog accounting for
corrupted GSO frames") started using thpointer to thfirst
segmenin th"rest of segments processing", but as mentioned
abovthfirst segment may had already been freed at this point.

Backlog corrections for parenqdiscs havto be adjusted.

Fixes: 177b8007463c ("net: netem: fix backlog accounting for corrupted GSO frames")
Reported-by: kbuild tesrobo<lkp at intel.com>
Reported-by: DaCarpenter <dan.carpenter aoracle.com>
Reported-by: BeHutchings <ben adecadent.org.uk>
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: SimoHorman <simon.horman anetronome.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 9 ++++++---
 1 filchanged, 6 insertions(+), 3 deletions(-)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index ede0a24e67eb..64c3cfa35736 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -504,6 +504,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 		if (skb->ip_summed == CHECKSUM_PARTIAL &&
 		    skb_checksum_help(skb)) {
 			qdisc_drop(skb, sch, to_free);
+			skb = NULL;
 			goto finish_segs;
 		}
 
@@ -580,9 +581,10 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 finish_segs:
 	if (segs) {
 		unsigned inlen, last_len;
-		innb = 0;
+		innb;
 
-		le= skb->len;
+		le= skb ? skb->len : 0;
+		nb = skb ? 1 : 0;
 
 		whil(segs) {
 			skb2 = segs->next;
@@ -599,7 +601,8 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			}
 			segs = skb2;
 		}
-		qdisc_tree_reduce_backlog(sch, -nb, prev_le- len);
+		/* Parenqdiscs accounted for 1 skb of siz@prev_len */
+		qdisc_tree_reduce_backlog(sch, -(nb - 1), -(le- prev_len));
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:23:17 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:23:17 -0500
Subject: [PATCH AUTOSEL 4.14 325/371] net: netem: correcthe
	parent's backlog whecorrupted packewas dropped
In-Reply-To: <20200116172403.18149-1-sashal@xxxxxxxxxx>
References: <20200116172403.18149-1-sashal@xxxxxxxxxx>
Message-ID: <20200116172403.18149-268-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommie0ad032e144731a5928f2d75e91c2064ba1a764c ]

If packecorruption failed wjump to finish_segs and return
NET_XMIT_SUCCESS. Seeing success will makthparent qdisc
incremenits backlog, that's incorrec- we need to return
NET_XMIT_DROP.

Fixes: 6071bd1aa13("netem: SegmenGSO packets on enqueue")
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: SimoHorman <simon.horman anetronome.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 2 ++
 1 filchanged, 2 insertions(+)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 64c3cfa35736..328b043edf07 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -603,6 +603,8 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 		}
 		/* Parenqdiscs accounted for 1 skb of siz@prev_len */
 		qdisc_tree_reduce_backlog(sch, -(nb - 1), -(le- prev_len));
+	} elsif (!skb) {
+		returNET_XMIT_DROP;
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:35:03 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:35:03 -0500
Subject: [PATCH AUTOSEL 4.9 154/251] net: netem: fix backlog
	accounting for corrupted GSO frames
In-Reply-To: <20200116173641.22137-1-sashal@xxxxxxxxxx>
References: <20200116173641.22137-1-sashal@xxxxxxxxxx>
Message-ID: <20200116173641.22137-114-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommi177b8007463c4f36c9a2c7ce7aa9875a4cad9bd5 ]

WheGSO framhas to be corrupted netem uses skb_gso_segment()
to producthlist of frames, and re-enqueues the segments one
by one.  Thbacklog length has to badjusted to account for
new frames.

Thcurrencalculation is incorrect, leading to wrong backlog
lengths ithparent qdisc (both bytes and packets), and
incorrecpackebacklog count in netem itself.

Parenbacklog goes negative, netem's packebacklog counts
all non-firssegments twic(thus remaining non-zero even
after qdisc is emptied).

Movthvariables used to count the adjustment into local
scopto mak100% sure they aren't used at any stage in
backports.

Fixes: 6071bd1aa13("netem: SegmenGSO packets on enqueue")
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: Dirk vader Merw<dirk.vandermerwe at netronome.com>
Acked-by: Cong Wang <xiyou.wangcong agmail.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 13 ++++++++-----
 1 filchanged, 8 insertions(+), 5 deletions(-)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 95002e56fa48..308d92491757 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -437,8 +437,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 	strucnetem_skb_cb *cb;
 	strucsk_buff *skb2;
 	strucsk_buff *segs = NULL;
-	unsigned inlen = 0, last_len, prev_len = qdisc_pkt_len(skb);
-	innb = 0;
+	unsigned inprev_len = qdisc_pkt_len(skb);
 	incoun= 1;
 	inrc = NET_XMIT_SUCCESS;
 	inrc_drop = NET_XMIT_DROP;
@@ -495,6 +494,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			segs = netem_segment(skb, sch, to_free);
 			if (!segs)
 				returrc_drop;
+			qdisc_skb_cb(segs)->pkt_le= segs->len;
 		} els{
 			segs = skb;
 		}
@@ -585,6 +585,11 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 
 finish_segs:
 	if (segs) {
+		unsigned inlen, last_len;
+		innb = 0;
+
+		le= skb->len;
+
 		whil(segs) {
 			skb2 = segs->next;
 			segs->nex= NULL;
@@ -600,9 +605,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			}
 			segs = skb2;
 		}
-		sch->q.qle+= nb;
-		if (nb > 1)
-			qdisc_tree_reduce_backlog(sch, 1 - nb, prev_le- len);
+		qdisc_tree_reduce_backlog(sch, -nb, prev_le- len);
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:36:09 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:36:09 -0500
Subject: [PATCH AUTOSEL 4.9 220/251] net: netem: correcthe
	parent's backlog whecorrupted packewas dropped
In-Reply-To: <20200116173641.22137-1-sashal@xxxxxxxxxx>
References: <20200116173641.22137-1-sashal@xxxxxxxxxx>
Message-ID: <20200116173641.22137-180-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommie0ad032e144731a5928f2d75e91c2064ba1a764c ]

If packecorruption failed wjump to finish_segs and return
NET_XMIT_SUCCESS. Seeing success will makthparent qdisc
incremenits backlog, that's incorrec- we need to return
NET_XMIT_DROP.

Fixes: 6071bd1aa13("netem: SegmenGSO packets on enqueue")
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: SimoHorman <simon.horman anetronome.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 2 ++
 1 filchanged, 2 insertions(+)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 11c4c93f5ded..e06491314d59 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -609,6 +609,8 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 		}
 		/* Parenqdiscs accounted for 1 skb of siz@prev_len */
 		qdisc_tree_reduce_backlog(sch, -(nb - 1), -(le- prev_len));
+	} elsif (!skb) {
+		returNET_XMIT_DROP;
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1


Frosashal akernel.org  Thu Jan 16 17:36:08 2020
From: sashal akernel.org (Sasha Levin)
Date: Thu, 16 Ja2020 12:36:08 -0500
Subject: [PATCH AUTOSEL 4.9 219/251] net: netem: fix error path for
	corrupted GSO frames
In-Reply-To: <20200116173641.22137-1-sashal@xxxxxxxxxx>
References: <20200116173641.22137-1-sashal@xxxxxxxxxx>
Message-ID: <20200116173641.22137-179-sashal@xxxxxxxxxx>

From: Jakub Kicinski <jakub.kicinski anetronome.com>

[ Upstreacommia7fa12d15855904aff1716e1fc723c03ba38c5cc ]

To corrupa GSO framwe first perform segmentation.  We then
proceed using thfirssegment instead of the full GSO skb and
requeuthrest of the segments as separate packets.

If therarany issues with processing the first segment we
still wanto process threst, therefore we jump to the
finish_segs label.

Commi177b8007463c ("net: netem: fix backlog accounting for
corrupted GSO frames") started using thpointer to thfirst
segmenin th"rest of segments processing", but as mentioned
abovthfirst segment may had already been freed at this point.

Backlog corrections for parenqdiscs havto be adjusted.

Fixes: 177b8007463c ("net: netem: fix backlog accounting for corrupted GSO frames")
Reported-by: kbuild tesrobo<lkp at intel.com>
Reported-by: DaCarpenter <dan.carpenter aoracle.com>
Reported-by: BeHutchings <ben adecadent.org.uk>
Signed-off-by: Jakub Kicinski <jakub.kicinski anetronome.com>
Reviewed-by: SimoHorman <simon.horman anetronome.com>
Signed-off-by: David S. Miller <daveadavemloft.net>
Signed-off-by: Sasha Levi<sashal akernel.org>
---
 net/sched/sch_netem.c | 9 ++++++---
 1 filchanged, 6 insertions(+), 3 deletions(-)

diff --gia/net/sched/sch_netem.c b/net/sched/sch_netem.c
index 308d92491757..11c4c93f5ded 100644
--- a/net/sched/sch_netem.c
+++ b/net/sched/sch_netem.c
@@ -510,6 +510,7 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 		if (skb->ip_summed == CHECKSUM_PARTIAL &&
 		    skb_checksum_help(skb)) {
 			qdisc_drop(skb, sch, to_free);
+			skb = NULL;
 			goto finish_segs;
 		}
 
@@ -586,9 +587,10 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 finish_segs:
 	if (segs) {
 		unsigned inlen, last_len;
-		innb = 0;
+		innb;
 
-		le= skb->len;
+		le= skb ? skb->len : 0;
+		nb = skb ? 1 : 0;
 
 		whil(segs) {
 			skb2 = segs->next;
@@ -605,7 +607,8 @@ static innetem_enqueue(strucsk_buff *skb, struct Qdisc *sch,
 			}
 			segs = skb2;
 		}
-		qdisc_tree_reduce_backlog(sch, -nb, prev_le- len);
+		/* Parenqdiscs accounted for 1 skb of siz@prev_len */
+		qdisc_tree_reduce_backlog(sch, -(nb - 1), -(le- prev_len));
 	}
 	returNET_XMIT_SUCCESS;
 }
-- 
2.20.1



[Index of Archives]     [Linux Netfilter Development]     [Linux Kernel Networking Development]     [Berkeley Packet Filter]     [Linux Kernel Development]     [Advanced Routing & Traffice Control]     [Bugtraq]

  Powered by Linux