All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net-next-2.6] sfq: fix sfq stats handling
@ 2010-12-22  6:14 Eric Dumazet
  2010-12-22  7:32 ` Jarek Poplawski
  2010-12-22 19:39 ` [PATCH net-next-2.6] sfq: fix sfq stats handling David Miller
  0 siblings, 2 replies; 7+ messages in thread
From: Eric Dumazet @ 2010-12-22  6:14 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Jarek Poplawski

David, since this one fixes a bug, could you apply it before the pending
SFQ patch (sch_sfq: allow big packets and be fair), I'll respin this one
if necessary.

Thanks

[PATCH net-next-2.6] sfq: fix sfq class stats handling

sfq_walk() runs without qdisc lock. By the time it selects a non empty
hash slot and sfq_dump_class_stats() is run (with lock held), slot might
have been freed : We then access q->slots[SFQ_EMPTY_SLOT], out of
bounds, and crash in slot_queue_walk()

On previous kernels, bug is here but out of bounds qs[SFQ_DEPTH] and
allot[SFQ_DEPTH] are located in struct sfq_sched_data, so no illegal
memory access happens, only possibly wrong data reported to user.

Also, slot_dequeue_tail() should make sure slot skb chain is correctly
terminated, or sfq_dump_class_stats() can access freed skbs.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Jarek Poplawski <jarkao2@gmail.com>
---
 net/sched/sch_sfq.c |   16 +++++++++++-----
 1 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 13322e8..6a2f88f 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -281,6 +281,7 @@ static inline struct sk_buff *slot_dequeue_tail(struct sfq_slot *slot)
 	struct sk_buff *skb = slot->skblist_prev;
 
 	slot->skblist_prev = skb->prev;
+	skb->prev->next = (struct sk_buff *)slot;
 	skb->next = skb->prev = NULL;
 	return skb;
 }
@@ -608,14 +609,19 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
 				struct gnet_dump *d)
 {
 	struct sfq_sched_data *q = qdisc_priv(sch);
-	const struct sfq_slot *slot = &q->slots[q->ht[cl - 1]];
-	struct gnet_stats_queue qs = { .qlen = slot->qlen };
-	struct tc_sfq_xstats xstats = { .allot = slot->allot };
+	sfq_index idx = q->ht[cl - 1];
+	struct gnet_stats_queue qs = { 0 };
+	struct tc_sfq_xstats xstats = { 0 };
 	struct sk_buff *skb;
 
-	slot_queue_walk(slot, skb)
-		qs.backlog += qdisc_pkt_len(skb);
+	if (idx != SFQ_EMPTY_SLOT) {
+		const struct sfq_slot *slot = &q->slots[idx];
 
+		xstats.allot = slot->allot;
+		qs.qlen = slot->qlen;
+		slot_queue_walk(slot, skb)
+			qs.backlog += qdisc_pkt_len(skb);
+	}
 	if (gnet_stats_copy_queue(d, &qs) < 0)
 		return -1;
 	return gnet_stats_copy_app(d, &xstats, sizeof(xstats));



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next-2.6] sfq: fix sfq stats handling
  2010-12-22  6:14 [PATCH net-next-2.6] sfq: fix sfq stats handling Eric Dumazet
@ 2010-12-22  7:32 ` Jarek Poplawski
  2010-12-30 15:02   ` [PATCH net-next-2.6] sfq: fix slot_dequeue_head() Eric Dumazet
  2010-12-22 19:39 ` [PATCH net-next-2.6] sfq: fix sfq stats handling David Miller
  1 sibling, 1 reply; 7+ messages in thread
From: Jarek Poplawski @ 2010-12-22  7:32 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev

On Wed, Dec 22, 2010 at 07:14:59AM +0100, Eric Dumazet wrote:
> David, since this one fixes a bug, could you apply it before the pending
> SFQ patch (sch_sfq: allow big packets and be fair), I'll respin this one
> if necessary.
> 
> Thanks
> 
> [PATCH net-next-2.6] sfq: fix sfq class stats handling
> 
> sfq_walk() runs without qdisc lock. By the time it selects a non empty
> hash slot and sfq_dump_class_stats() is run (with lock held), slot might
> have been freed : We then access q->slots[SFQ_EMPTY_SLOT], out of
> bounds, and crash in slot_queue_walk()
> 
> On previous kernels, bug is here but out of bounds qs[SFQ_DEPTH] and
> allot[SFQ_DEPTH] are located in struct sfq_sched_data, so no illegal
> memory access happens, only possibly wrong data reported to user.

Yes, nice catch!

> Also, slot_dequeue_tail() should make sure slot skb chain is correctly
> terminated, or sfq_dump_class_stats() can access freed skbs.

...and a good hint for code reusing ;-)

Thanks,
Jarek P.

> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Jarek Poplawski <jarkao2@gmail.com>
> ---
>  net/sched/sch_sfq.c |   16 +++++++++++-----
>  1 files changed, 11 insertions(+), 5 deletions(-)
> 
> diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
> index 13322e8..6a2f88f 100644
> --- a/net/sched/sch_sfq.c
> +++ b/net/sched/sch_sfq.c
> @@ -281,6 +281,7 @@ static inline struct sk_buff *slot_dequeue_tail(struct sfq_slot *slot)
>  	struct sk_buff *skb = slot->skblist_prev;
>  
>  	slot->skblist_prev = skb->prev;
> +	skb->prev->next = (struct sk_buff *)slot;
>  	skb->next = skb->prev = NULL;
>  	return skb;
>  }
> @@ -608,14 +609,19 @@ static int sfq_dump_class_stats(struct Qdisc *sch, unsigned long cl,
>  				struct gnet_dump *d)
>  {
>  	struct sfq_sched_data *q = qdisc_priv(sch);
> -	const struct sfq_slot *slot = &q->slots[q->ht[cl - 1]];
> -	struct gnet_stats_queue qs = { .qlen = slot->qlen };
> -	struct tc_sfq_xstats xstats = { .allot = slot->allot };
> +	sfq_index idx = q->ht[cl - 1];
> +	struct gnet_stats_queue qs = { 0 };
> +	struct tc_sfq_xstats xstats = { 0 };
>  	struct sk_buff *skb;
>  
> -	slot_queue_walk(slot, skb)
> -		qs.backlog += qdisc_pkt_len(skb);
> +	if (idx != SFQ_EMPTY_SLOT) {
> +		const struct sfq_slot *slot = &q->slots[idx];
>  
> +		xstats.allot = slot->allot;
> +		qs.qlen = slot->qlen;
> +		slot_queue_walk(slot, skb)
> +			qs.backlog += qdisc_pkt_len(skb);
> +	}
>  	if (gnet_stats_copy_queue(d, &qs) < 0)
>  		return -1;
>  	return gnet_stats_copy_app(d, &xstats, sizeof(xstats));
> 
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next-2.6] sfq: fix sfq stats handling
  2010-12-22  6:14 [PATCH net-next-2.6] sfq: fix sfq stats handling Eric Dumazet
  2010-12-22  7:32 ` Jarek Poplawski
@ 2010-12-22 19:39 ` David Miller
  1 sibling, 0 replies; 7+ messages in thread
From: David Miller @ 2010-12-22 19:39 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, jarkao2

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 22 Dec 2010 07:14:59 +0100

> David, since this one fixes a bug, could you apply it before the pending
> SFQ patch (sch_sfq: allow big packets and be fair), I'll respin this one
> if necessary.
> 
> Thanks
> 
> [PATCH net-next-2.6] sfq: fix sfq class stats handling
> 
> sfq_walk() runs without qdisc lock. By the time it selects a non empty
> hash slot and sfq_dump_class_stats() is run (with lock held), slot might
> have been freed : We then access q->slots[SFQ_EMPTY_SLOT], out of
> bounds, and crash in slot_queue_walk()
> 
> On previous kernels, bug is here but out of bounds qs[SFQ_DEPTH] and
> allot[SFQ_DEPTH] are located in struct sfq_sched_data, so no illegal
> memory access happens, only possibly wrong data reported to user.
> 
> Also, slot_dequeue_tail() should make sure slot skb chain is correctly
> terminated, or sfq_dump_class_stats() can access freed skbs.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Jarek Poplawski <jarkao2@gmail.com>

Applied, thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH net-next-2.6] sfq: fix slot_dequeue_head()
  2010-12-22  7:32 ` Jarek Poplawski
@ 2010-12-30 15:02   ` Eric Dumazet
  2010-12-30 17:49     ` Jarek Poplawski
  0 siblings, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2010-12-30 15:02 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, Jarek Poplawski

Le mercredi 22 décembre 2010 à 07:32 +0000, Jarek Poplawski a écrit :
> > Also, slot_dequeue_tail() should make sure slot skb chain is correctly
> > terminated, or sfq_dump_class_stats() can access freed skbs.
> 
> ...and a good hint for code reusing ;-)

Yes, and of course same fix is needed in slot_dequeue_head(), as further
testing on my side made it pretty clear.

I was adding possibility to have more packets queued in SFQ (more
packets than max number of flows) and got unexpected crashes.

Reverting to net-next-2.6, I still got crashes. Oops.

[PATCH net-next-2.6] sfq: fix slot_dequeue_head()

slot_dequeue_head() should make sure slot skb chain is correct in both
ways, or we can crash if all possible flows are in use.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Jarek Poplawski <jarkao2@gmail.com>
---
 net/sched/sch_sfq.c |    1 +
 1 files changed, 1 insertion(+)

diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 6a2f88f..3977e56 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -292,6 +292,7 @@ static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot)
 	struct sk_buff *skb = slot->skblist_next;
 
 	slot->skblist_next = skb->next;
+	skb->next->prev = (struct sk_buff *)slot;
 	skb->next = skb->prev = NULL;
 	return skb;
 }



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next-2.6] sfq: fix slot_dequeue_head()
  2010-12-30 15:02   ` [PATCH net-next-2.6] sfq: fix slot_dequeue_head() Eric Dumazet
@ 2010-12-30 17:49     ` Jarek Poplawski
  2010-12-30 21:31       ` Eric Dumazet
  0 siblings, 1 reply; 7+ messages in thread
From: Jarek Poplawski @ 2010-12-30 17:49 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: David Miller, netdev

On Thu, Dec 30, 2010 at 04:02:48PM +0100, Eric Dumazet wrote:
> Le mercredi 22 décembre 2010 ?? 07:32 +0000, Jarek Poplawski a écrit :
> > > Also, slot_dequeue_tail() should make sure slot skb chain is correctly
> > > terminated, or sfq_dump_class_stats() can access freed skbs.
> > 
> > ...and a good hint for code reusing ;-)
> 
> Yes, and of course same fix is needed in slot_dequeue_head(), as further
> testing on my side made it pretty clear.
> 
> I was adding possibility to have more packets queued in SFQ (more
> packets than max number of flows) and got unexpected crashes.
> 
> Reverting to net-next-2.6, I still got crashes. Oops.
> 
> [PATCH net-next-2.6] sfq: fix slot_dequeue_head()
> 
> slot_dequeue_head() should make sure slot skb chain is correct in both
> ways, or we can crash if all possible flows are in use.

Nice scenario ;-) Of course, it's easy to guess I looked for something
like this after your previous fix and missed that :-| Btw, it looks
like slot_queue_init() could go back to sfq_init() now.

Jarek P.

> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
> Cc: Jarek Poplawski <jarkao2@gmail.com>
> ---
>  net/sched/sch_sfq.c |    1 +
>  1 files changed, 1 insertion(+)
> 
> diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
> index 6a2f88f..3977e56 100644
> --- a/net/sched/sch_sfq.c
> +++ b/net/sched/sch_sfq.c
> @@ -292,6 +292,7 @@ static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot)
>  	struct sk_buff *skb = slot->skblist_next;
>  
>  	slot->skblist_next = skb->next;
> +	skb->next->prev = (struct sk_buff *)slot;
>  	skb->next = skb->prev = NULL;
>  	return skb;
>  }
> 
> 

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next-2.6] sfq: fix slot_dequeue_head()
  2010-12-30 17:49     ` Jarek Poplawski
@ 2010-12-30 21:31       ` Eric Dumazet
  2010-12-31 20:49         ` David Miller
  0 siblings, 1 reply; 7+ messages in thread
From: Eric Dumazet @ 2010-12-30 21:31 UTC (permalink / raw)
  To: Jarek Poplawski; +Cc: David Miller, netdev

Le jeudi 30 décembre 2010 à 18:49 +0100, Jarek Poplawski a écrit :

> Nice scenario ;-) Of course, it's easy to guess I looked for something
> like this after your previous fix and missed that :-| Btw, it looks
> like slot_queue_init() could go back to sfq_init() now.
> 

Indeed, I tested following combined patch and all is good.

Thanks Jarek !

[PATCH v2 net-next-2.6] sfq: fix slot_dequeue_head()

slot_dequeue_head() should make sure slot skb chain is correct in both
ways, or we can crash if all possible flows are in use.

Jarek pointed out slot_queue_init() can now be done in sfq_init() once,
instead each time a flow is setup.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Jarek Poplawski <jarkao2@gmail.com>
---
 net/sched/sch_sfq.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 6a2f88f..02fa1dd 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -292,6 +292,7 @@ static inline struct sk_buff *slot_dequeue_head(struct sfq_slot *slot)
 	struct sk_buff *skb = slot->skblist_next;
 
 	slot->skblist_next = skb->next;
+	skb->next->prev = (struct sk_buff *)slot;
 	skb->next = skb->prev = NULL;
 	return skb;
 }
@@ -375,7 +376,6 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch)
 		q->ht[hash] = x;
 		slot = &q->slots[x];
 		slot->hash = hash;
-		slot_queue_init(slot);
 	}
 
 	/* If selected queue has length q->limit, do simple tail drop,
@@ -533,8 +533,10 @@ static int sfq_init(struct Qdisc *sch, struct nlattr *opt)
 			return err;
 	}
 
-	for (i = 0; i < SFQ_SLOTS; i++)
+	for (i = 0; i < SFQ_SLOTS; i++) {
+		slot_queue_init(&q->slots[i]);
 		sfq_link(q, i);
+	}
 	return 0;
 }
 



^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH net-next-2.6] sfq: fix slot_dequeue_head()
  2010-12-30 21:31       ` Eric Dumazet
@ 2010-12-31 20:49         ` David Miller
  0 siblings, 0 replies; 7+ messages in thread
From: David Miller @ 2010-12-31 20:49 UTC (permalink / raw)
  To: eric.dumazet; +Cc: jarkao2, netdev

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Thu, 30 Dec 2010 22:31:09 +0100

> [PATCH v2 net-next-2.6] sfq: fix slot_dequeue_head()
> 
> slot_dequeue_head() should make sure slot skb chain is correct in both
> ways, or we can crash if all possible flows are in use.
> 
> Jarek pointed out slot_queue_init() can now be done in sfq_init() once,
> instead each time a flow is setup.
> 
> Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>

Also applied, thanks.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2010-12-31 20:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-22  6:14 [PATCH net-next-2.6] sfq: fix sfq stats handling Eric Dumazet
2010-12-22  7:32 ` Jarek Poplawski
2010-12-30 15:02   ` [PATCH net-next-2.6] sfq: fix slot_dequeue_head() Eric Dumazet
2010-12-30 17:49     ` Jarek Poplawski
2010-12-30 21:31       ` Eric Dumazet
2010-12-31 20:49         ` David Miller
2010-12-22 19:39 ` [PATCH net-next-2.6] sfq: fix sfq stats handling David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.