aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_flowlabel.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-10-18 08:14:58 -0400
committerDavid S. Miller <davem@davemloft.net>2007-10-18 08:14:58 -0400
commit04028045a12ba941c579d0f3238489333ac18ea4 (patch)
treee12d202ef1e17047742ddb9a70731ebc651f6c11 /net/ipv6/ip6_flowlabel.c
parent009e8c965fd72a78636b9a96c7015109c5c70176 (diff)
[IPV6]: Lost locking when inserting a flowlabel in ipv6_fl_list
The new flowlabels should be inserted into the sock list under the ip6_sk_fl_lock. This was lost in one place. This list is naturally protected with the socket lock, but the fl6_sock_lookup() is called without it, so another protection is required. Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/ip6_flowlabel.c')
-rw-r--r--net/ipv6/ip6_flowlabel.c20
1 files changed, 12 insertions, 8 deletions
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 217d60f9fc80..8550df20f984 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -409,6 +409,16 @@ static int ipv6_opt_cmp(struct ipv6_txoptions *o1, struct ipv6_txoptions *o2)
409 return 0; 409 return 0;
410} 410}
411 411
412static inline void fl_link(struct ipv6_pinfo *np, struct ipv6_fl_socklist *sfl,
413 struct ip6_flowlabel *fl)
414{
415 write_lock_bh(&ip6_sk_fl_lock);
416 sfl->fl = fl;
417 sfl->next = np->ipv6_fl_list;
418 np->ipv6_fl_list = sfl;
419 write_unlock_bh(&ip6_sk_fl_lock);
420}
421
412int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) 422int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
413{ 423{
414 int err; 424 int err;
@@ -513,11 +523,7 @@ int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen)
513 fl1->linger = fl->linger; 523 fl1->linger = fl->linger;
514 if ((long)(fl->expires - fl1->expires) > 0) 524 if ((long)(fl->expires - fl1->expires) > 0)
515 fl1->expires = fl->expires; 525 fl1->expires = fl->expires;
516 write_lock_bh(&ip6_sk_fl_lock); 526 fl_link(np, sfl1, fl1);
517 sfl1->fl = fl1;
518 sfl1->next = np->ipv6_fl_list;
519 np->ipv6_fl_list = sfl1;
520 write_unlock_bh(&ip6_sk_fl_lock);
521 fl_free(fl); 527 fl_free(fl);
522 return 0; 528 return 0;
523 529
@@ -545,9 +551,7 @@ release:
545 } 551 }
546 } 552 }
547 553
548 sfl1->fl = fl; 554 fl_link(np, sfl1, fl);
549 sfl1->next = np->ipv6_fl_list;
550 np->ipv6_fl_list = sfl1;
551 return 0; 555 return 0;
552 556
553 default: 557 default: