lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <1abb4a1f.6499.15dc5dae314.Coremail.gfree.wind@vip.163.com>
Date:   Wed, 9 Aug 2017 15:17:22 +0800 (CST)
From:   "Gao Feng" <gfree.wind@....163.com>
To:     "Gao Feng" <gfree.wind@....163.com>
Cc:     "Cong Wang" <xiyou.wangcong@...il.com>, xeb@...l.ru,
        "David Miller" <davem@...emloft.net>,
        "Linux Kernel Network Developers" <netdev@...r.kernel.org>
Subject: Re:Re:Re: Re:Re: Re: [PATCH net] ppp: Fix a scheduling-while-atomic
 bug in del_chan

At 2017-08-09 13:13:53, "Gao Feng" <gfree.wind@....163.com> wrote:
>At 2017-08-09 03:45:53, "Cong Wang" <xiyou.wangcong@...il.com> wrote:
>>On Mon, Aug 7, 2017 at 6:10 PM, Gao Feng <gfree.wind@....163.com> wrote:
>>>
>>> Sorry, I don't get you clearly. Why the sock_hold() isn't helpful?
>>
>>I already told you, the dereference happends before sock_hold().
>>
>>        sock = rcu_dereference(callid_sock[call_id]);
>>        if (sock) {
>>                opt = &sock->proto.pptp;
>>                if (opt->dst_addr.sin_addr.s_addr != s_addr) <=== HERE
>>                        sock = NULL;
>>                else
>>                        sock_hold(sk_pppox(sock));
>>        }
>>
>>If we don't wait for readers properly, sock could be freed at the
>>same time when deference it.
>
>Maybe I didn't show my explanation clearly.
>I think it won't happen as I mentioned in the last email.
>Because the pptp_release invokes the synchronize_rcu to make sure it, and actually there is no one which would invoke del_chan except pptp_release.
>It is guaranteed by that the pptp_release doesn't put the sock refcnt until complete all cleanup include marking sk_state as PPPOX_DEAD. 
>
>In other words, even though the pptp_release is not the last user of this sock, the other one wouldn't invoke del_chan in pptp_sock_destruct.
>Because the condition "!(sk->sk_state & PPPOX_DEAD)" must be false. 
>
>As summary, the del_chan and pppox_unbind_sock in pptp_sock_destruct are unnecessary. 
>And it even brings confusing.
>
>Best Regards
>Feng
>
>>
>>> The pptp_release invokes synchronize_rcu after del_chan, it could make sure the others has increased the sock refcnt if necessary
>>> and the lookup is over.
>>> There is no one could get the sock after synchronize_rcu in pptp_release.
>>
>>
>>If this were true, then this code in pptp_sock_destruct()
>>would be unneeded:
>>
>>        if (!(sk->sk_state & PPPOX_DEAD)) {
>>                del_chan(pppox_sk(sk));
>>                pppox_unbind_sock(sk);
>>        }
>>
>>
>>>
>>>
>>> But I think about another problem.
>>> It seems the pptp_sock_destruct should not invoke del_chan and pppox_unbind_sock.
>>> Because when the sock refcnt is 0, the pptp_release must have be invoked already.
>>>
>>
>>
>>I don't know. Looks like sock_orphan() is only called
>>in pptp_release(), but I am not sure if there is a case
>>we call sock destructor before release.
>>
>>Also note, this socket is very special, it doesn't support
>>poll(), sendmsg() or recvmsg()..
>
>
>

Hi Cong,

Actually I have one question about the SOCK_RCU_FREE.
I don't think it could resolve the issue you raised even though it exists really.

I checked the SOCK_RCU_FREE, it just defer the __sk_destruct after one rcu period.
But when it performs, someone still could find this sock by callid during the del_chan period and it may still deference the sock which may freed soon.

The right flow should be following.
del_chan()
wait a rcu period
sock_put() ------------ It is safe that someone gets the sock because it already hold sock refcnt.

When using SOCK_RCU_FREE, its flow would be following.
wait a rcu period
del_chan()
free the sock directly -------- no sock refcnt check again.
Because the del_chan happens after rcu wait, not before, so it isn't helpful with SOCK_RCU_FREE.

I don't know if I misunderstand the SOCK_RCU_FREE usage.

But it is a good news that the del_chan is only invoked in pptp_release actually and it would wait a rcu period before sock_put.

Best Regards
Feng


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ