diff options
author | Pavel Emelyanov <xemul@openvz.org> | 2007-10-18 08:14:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-10-18 08:14:58 -0400 |
commit | 04028045a12ba941c579d0f3238489333ac18ea4 (patch) | |
tree | e12d202ef1e17047742ddb9a70731ebc651f6c11 /net/ipv6/ip6_flowlabel.c | |
parent | 009e8c965fd72a78636b9a96c7015109c5c70176 (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.c | 20 |
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 | ||
412 | static 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 | |||
412 | int ipv6_flowlabel_opt(struct sock *sk, char __user *optval, int optlen) | 422 | int 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: |