.. | .. |
---|
429 | 429 | if (optlen < sizeof(int)) |
---|
430 | 430 | goto e_inval; |
---|
431 | 431 | if (val == PF_INET) { |
---|
432 | | - struct ipv6_txoptions *opt; |
---|
433 | | - struct sk_buff *pktopt; |
---|
434 | | - |
---|
435 | 432 | if (sk->sk_type == SOCK_RAW) |
---|
436 | 433 | break; |
---|
437 | 434 | |
---|
.. | .. |
---|
462 | 459 | break; |
---|
463 | 460 | } |
---|
464 | 461 | |
---|
465 | | - fl6_free_socklist(sk); |
---|
466 | 462 | __ipv6_sock_mc_close(sk); |
---|
467 | 463 | __ipv6_sock_ac_close(sk); |
---|
468 | 464 | |
---|
.. | .. |
---|
497 | 493 | sk->sk_socket->ops = &inet_dgram_ops; |
---|
498 | 494 | sk->sk_family = PF_INET; |
---|
499 | 495 | } |
---|
500 | | - opt = xchg((__force struct ipv6_txoptions **)&np->opt, |
---|
501 | | - NULL); |
---|
502 | | - if (opt) { |
---|
503 | | - atomic_sub(opt->tot_len, &sk->sk_omem_alloc); |
---|
504 | | - txopt_put(opt); |
---|
505 | | - } |
---|
506 | | - pktopt = xchg(&np->pktoptions, NULL); |
---|
507 | | - kfree_skb(pktopt); |
---|
| 496 | + |
---|
| 497 | + /* Disable all options not to allocate memory anymore, |
---|
| 498 | + * but there is still a race. See the lockless path |
---|
| 499 | + * in udpv6_sendmsg() and ipv6_local_rxpmtu(). |
---|
| 500 | + */ |
---|
| 501 | + np->rxopt.all = 0; |
---|
| 502 | + |
---|
| 503 | + inet6_cleanup_sock(sk); |
---|
508 | 504 | |
---|
509 | 505 | /* |
---|
510 | 506 | * ... and add it to the refcnt debug socks count |
---|