Thread (7 messages) 7 messages, 3 authors, 2020-02-10

Re: [PATCH] nbd: fix potential NULL pointer fault in connect and disconnect process

From: sunke (E) <hidden>
Date: 2020-02-10 09:15:21
Also in: lkml

Hi Mike

Your idea looks good.

Thanks,
Sun Ke

在 2020/2/10 11:16, Mike Christie 写道:
On 01/19/2020 01:10 AM, sunke (E) wrote:
quoted
Thanks for your detailed suggestions.

在 2020/1/18 1:32, Mike Christie 写道:
quoted
On 01/17/2020 05:50 AM, Sun Ke wrote:
quoted
Connect and disconnect a nbd device repeatedly, will cause
NULL pointer fault.

It will appear by the steps:
1. Connect the nbd device and disconnect it, but now nbd device
     is not disconnected totally.
2. Connect the same nbd device again immediately, it will fail
     in nbd_start_device with a EBUSY return value.
3. Wait a second to make sure the last config_refs is reduced
     and run nbd_config_put to disconnect the nbd device totally.
4. Start another process to open the nbd_device, config_refs
     will increase and at the same time disconnect it.
Just to make sure I understood this, for step 4 the process is doing:

open(/dev/nbdX);
ioctl(NBD_DISCONNECT, /dev/nbdX) or nbd_genl_disconnect(for /dev/nbdX)

?
do nbd_genl_disconnect(for /dev/nbdX);
I tested it. Connect /dev/nbdX
through ioctl interface by nbd-client -L -N export localhost /dev/nbdX and
through netlink interface by nbd-client localhost XXXX /dev/nbdX,
disconnect /dev/nbdX by nbd-client -d /dev/nbdX.
Both call nbd_genl_disconnect(for /dev/nbdX) and both contain the same
null pointer dereference.
quoted
There is no successful NBD_DO_IT / nbd_genl_connect between the open and
disconnect calls at step #4, because it would normally be done at #2 and
that failed. nbd_disconnect_and_put could then reference a null
recv_workq. If we are also racing with a close() then that could free
the device/config from under nbd_disconnect_and_put.
Yes, nbd_disconnect_and_put could then reference a null recv_workq.
Hey Sunke

How about the attached patch. I am still testing it. The basic idea is
that we need to do a flush whenever we have done a sock_shutdown and are
in the disconnect/connect/clear sock path, so it just adds the flush in
that function. We then do not need to keep adding these flushes everywhere.
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help