Message ID | 1481798947-18287-2-git-send-email-luis.henriques@canonical.com |
---|---|
State | New |
Headers | show |
On 15/12/16 10:49, Luis Henriques wrote: > From: Herbert Xu <herbert@gondor.apana.org.au> > > When we free cb->skb after a dump, we do it after releasing the > lock. This means that a new dump could have started in the time > being and we'll end up freeing their skb instead of ours. > > This patch saves the skb and module before we unlock so we free > the right memory. > > Fixes: 16b304f3404f ("netlink: Eliminate kmalloc in netlink dump operation.") > Reported-by: Baozeng Ding <sploving1@gmail.com> > Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> > Acked-by: Cong Wang <xiyou.wangcong@gmail.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (cherry picked from commit 92964c79b357efd980812c4de5c1fd2ec8bb5520) > CVE-2016-9806 > Signed-off-by: Luis Henriques <luis.henriques@canonical.com> > --- > net/netlink/af_netlink.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c > index f4bc7ddc5840..0038f9bb8a09 100644 > --- a/net/netlink/af_netlink.c > +++ b/net/netlink/af_netlink.c > @@ -2663,6 +2663,7 @@ static int netlink_dump(struct sock *sk) > struct netlink_callback *cb; > struct sk_buff *skb = NULL; > struct nlmsghdr *nlh; > + struct module *module; > int len, err = -ENOBUFS; > int alloc_size; > > @@ -2732,9 +2733,11 @@ static int netlink_dump(struct sock *sk) > cb->done(cb); > > nlk->cb_running = false; > + module = cb->module; > + skb = cb->skb; > mutex_unlock(nlk->cb_mutex); > - module_put(cb->module); > - consume_skb(cb->skb); > + module_put(module); > + consume_skb(skb); > return 0; > > errout_skb: > Acked-by: Colin Ian King <colin.king@canonical.com>
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index f4bc7ddc5840..0038f9bb8a09 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -2663,6 +2663,7 @@ static int netlink_dump(struct sock *sk) struct netlink_callback *cb; struct sk_buff *skb = NULL; struct nlmsghdr *nlh; + struct module *module; int len, err = -ENOBUFS; int alloc_size; @@ -2732,9 +2733,11 @@ static int netlink_dump(struct sock *sk) cb->done(cb); nlk->cb_running = false; + module = cb->module; + skb = cb->skb; mutex_unlock(nlk->cb_mutex); - module_put(cb->module); - consume_skb(cb->skb); + module_put(module); + consume_skb(skb); return 0; errout_skb: