* [PATCH net-2.6.25] [IPV6] ADDRLABEL: Fix double free on label deletion.
@ 2008-01-28 12:02 YOSHIFUJI Hideaki / 吉藤英明
2008-01-29 0:21 ` David Miller
` (2 more replies)
0 siblings, 3 replies; 5+ messages in thread
From: YOSHIFUJI Hideaki / 吉藤英明 @ 2008-01-28 12:02 UTC (permalink / raw)
To: davem; +Cc: yoshfuji, mitch, netdev
If an entry is being deleted because it has only one reference,
we immediately delete it and blindly register the rcu handler for it,
This results in oops by double freeing that object.
This patch fixes it by consolidating the code paths for the deletion;
let its rcu handler delete the object if it has no more reference.
Bug was found by Mitsuru Chinen <mitch@linux.vnet.ibm.com>
Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
---
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 6f1ca60..7a706c4 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -106,6 +106,11 @@ static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
kfree(p);
}
+static void ip6addrlbl_free_rcu(struct rcu_head *h)
+{
+ ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
+}
+
static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
{
return atomic_inc_not_zero(&p->refcnt);
@@ -114,12 +119,7 @@ static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
{
if (atomic_dec_and_test(&p->refcnt))
- ip6addrlbl_free(p);
-}
-
-static void ip6addrlbl_free_rcu(struct rcu_head *h)
-{
- ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
+ call_rcu(&p->rcu, ip6addrlbl_free_rcu);
}
/* Find label */
@@ -240,7 +240,6 @@ int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
}
hlist_replace_rcu(&p->list, &newp->list);
ip6addrlbl_put(p);
- call_rcu(&p->rcu, ip6addrlbl_free_rcu);
goto out;
} else if ((p->prefixlen == newp->prefixlen && !p->ifindex) ||
(p->prefixlen < newp->prefixlen)) {
@@ -300,7 +299,6 @@ int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
ipv6_addr_equal(&p->prefix, prefix)) {
hlist_del_rcu(&p->list);
ip6addrlbl_put(p);
- call_rcu(&p->rcu, ip6addrlbl_free_rcu);
ret = 0;
break;
}
--
YOSHIFUJI Hideaki @ USAGI Project <yoshfuji@linux-ipv6.org>
GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
^ permalink raw reply related [flat|nested] 5+ messages in thread* Re: [PATCH net-2.6.25] [IPV6] ADDRLABEL: Fix double free on label deletion.
2008-01-28 12:02 [PATCH net-2.6.25] [IPV6] ADDRLABEL: Fix double free on label deletion YOSHIFUJI Hideaki / 吉藤英明
@ 2008-01-29 0:21 ` David Miller
2008-01-29 20:59 ` Paul E. McKenney
2008-02-01 6:37 ` [PATCH] add if_addrlabel.h to sanitized headers Stephen Hemminger
2 siblings, 0 replies; 5+ messages in thread
From: David Miller @ 2008-01-29 0:21 UTC (permalink / raw)
To: yoshfuji; +Cc: mitch, netdev
From: YOSHIFUJI Hideaki / 吉藤英明 <yoshfuji@linux-ipv6.org>
Date: Mon, 28 Jan 2008 21:02:22 +0900 (JST)
> If an entry is being deleted because it has only one reference,
> we immediately delete it and blindly register the rcu handler for it,
> This results in oops by double freeing that object.
>
> This patch fixes it by consolidating the code paths for the deletion;
> let its rcu handler delete the object if it has no more reference.
>
> Bug was found by Mitsuru Chinen <mitch@linux.vnet.ibm.com>
>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Applied, thank you.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH net-2.6.25] [IPV6] ADDRLABEL: Fix double free on label deletion.
2008-01-28 12:02 [PATCH net-2.6.25] [IPV6] ADDRLABEL: Fix double free on label deletion YOSHIFUJI Hideaki / 吉藤英明
2008-01-29 0:21 ` David Miller
@ 2008-01-29 20:59 ` Paul E. McKenney
2008-02-01 6:37 ` [PATCH] add if_addrlabel.h to sanitized headers Stephen Hemminger
2 siblings, 0 replies; 5+ messages in thread
From: Paul E. McKenney @ 2008-01-29 20:59 UTC (permalink / raw)
To: YOSHIFUJI Hideaki / 吉藤英明; +Cc: davem, mitch, netdev
On Mon, Jan 28, 2008 at 09:02:22PM +0900, YOSHIFUJI Hideaki / 吉藤英明 wrote:
> If an entry is being deleted because it has only one reference,
> we immediately delete it and blindly register the rcu handler for it,
> This results in oops by double freeing that object.
>
> This patch fixes it by consolidating the code paths for the deletion;
> let its rcu handler delete the object if it has no more reference.
>
> Bug was found by Mitsuru Chinen <mitch@linux.vnet.ibm.com>
Good catch!!!
Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
> Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
> ---
>
> diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
> index 6f1ca60..7a706c4 100644
> --- a/net/ipv6/addrlabel.c
> +++ b/net/ipv6/addrlabel.c
> @@ -106,6 +106,11 @@ static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
> kfree(p);
> }
>
> +static void ip6addrlbl_free_rcu(struct rcu_head *h)
> +{
> + ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
> +}
> +
> static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
> {
> return atomic_inc_not_zero(&p->refcnt);
> @@ -114,12 +119,7 @@ static inline int ip6addrlbl_hold(struct ip6addrlbl_entry *p)
> static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
> {
> if (atomic_dec_and_test(&p->refcnt))
> - ip6addrlbl_free(p);
> -}
> -
> -static void ip6addrlbl_free_rcu(struct rcu_head *h)
> -{
> - ip6addrlbl_free(container_of(h, struct ip6addrlbl_entry, rcu));
> + call_rcu(&p->rcu, ip6addrlbl_free_rcu);
> }
>
> /* Find label */
> @@ -240,7 +240,6 @@ int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
> }
> hlist_replace_rcu(&p->list, &newp->list);
> ip6addrlbl_put(p);
> - call_rcu(&p->rcu, ip6addrlbl_free_rcu);
> goto out;
> } else if ((p->prefixlen == newp->prefixlen && !p->ifindex) ||
> (p->prefixlen < newp->prefixlen)) {
> @@ -300,7 +299,6 @@ int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
> ipv6_addr_equal(&p->prefix, prefix)) {
> hlist_del_rcu(&p->list);
> ip6addrlbl_put(p);
> - call_rcu(&p->rcu, ip6addrlbl_free_rcu);
> ret = 0;
> break;
> }
>
> --
> YOSHIFUJI Hideaki @ USAGI Project <yoshfuji@linux-ipv6.org>
> GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 5+ messages in thread* [PATCH] add if_addrlabel.h to sanitized headers
2008-01-28 12:02 [PATCH net-2.6.25] [IPV6] ADDRLABEL: Fix double free on label deletion YOSHIFUJI Hideaki / 吉藤英明
2008-01-29 0:21 ` David Miller
2008-01-29 20:59 ` Paul E. McKenney
@ 2008-02-01 6:37 ` Stephen Hemminger
2008-02-05 11:19 ` David Miller
2 siblings, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2008-02-01 6:37 UTC (permalink / raw)
Cc: netdev
if_addrlabel.h is needed for iproute2 usage.
Signed-off-by: Stephen Hemminger <stephen.hemminger@vyatta.com>
---
include/linux/Kbuild | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/include/linux/Kbuild b/include/linux/Kbuild
index 85b2482..ce9d0fd 100644
--- a/include/linux/Kbuild
+++ b/include/linux/Kbuild
@@ -218,6 +218,7 @@ unifdef-y += i2c-dev.h
unifdef-y += icmp.h
unifdef-y += icmpv6.h
unifdef-y += if_addr.h
+unifdef-y += if_addrlabel.h
unifdef-y += if_arp.h
unifdef-y += if_bridge.h
unifdef-y += if_ec.h
--
1.5.3.8
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2008-02-05 11:18 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-28 12:02 [PATCH net-2.6.25] [IPV6] ADDRLABEL: Fix double free on label deletion YOSHIFUJI Hideaki / 吉藤英明
2008-01-29 0:21 ` David Miller
2008-01-29 20:59 ` Paul E. McKenney
2008-02-01 6:37 ` [PATCH] add if_addrlabel.h to sanitized headers Stephen Hemminger
2008-02-05 11:19 ` David Miller
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).