Stefano Garzarella
2019-Oct-11 13:07 UTC
[PATCH net 0/2] vsock: don't allow half-closed socket in the host transports
We are implementing a test suite for the VSOCK sockets and we discovered that vmci_transport never allowed half-closed socket on the host side. As Jorgen explained [1] this is due to the implementation of VMCI. Since we want to have the same behaviour across all transports, this series adds a section in the "Implementation notes" to exaplain this behaviour, and changes the vhost_transport to behave the same way. [1] https://patchwork.ozlabs.org/cover/847998/#1831400 Stefano Garzarella (2): vsock: add half-closed socket details in the implementation notes vhost/vsock: don't allow half-closed socket in the host drivers/vhost/vsock.c | 17 ++++++++++++++++- net/vmw_vsock/af_vsock.c | 4 ++++ 2 files changed, 20 insertions(+), 1 deletion(-) -- 2.21.0
Stefano Garzarella
2019-Oct-11 13:07 UTC
[PATCH net 1/2] vsock: add half-closed socket details in the implementation notes
vmci_transport never allowed half-closed socket on the host side. Since we want to have the same behaviour across all transports, we add a section in the "Implementation notes". Cc: Jorgen Hansen <jhansen at vmware.com> Cc: Adit Ranadive <aditr at vmware.com> Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> --- net/vmw_vsock/af_vsock.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 2ab43b2bba31..27df57c2024b 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -83,6 +83,10 @@ * TCP_ESTABLISHED - connected * TCP_CLOSING - disconnecting * TCP_LISTEN - listening + * + * - Half-closed socket is supported only on the guest side. recv() on the host + * side should return EOF when the guest closes a connection, also if some + * data is still in the receive queue. */ #include <linux/types.h> -- 2.21.0
Stefano Garzarella
2019-Oct-11 13:07 UTC
[PATCH net 2/2] vhost/vsock: don't allow half-closed socket in the host
vmci_transport never allowed half-closed socket on the host side. In order to provide the same behaviour, we changed the vhost_transport_stream_has_data() to return 0 (no data available) if the peer (guest) closed the connection. Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> --- drivers/vhost/vsock.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c index 9f57736fe15e..754120aa4478 100644 --- a/drivers/vhost/vsock.c +++ b/drivers/vhost/vsock.c @@ -58,6 +58,21 @@ static u32 vhost_transport_get_local_cid(void) return VHOST_VSOCK_DEFAULT_HOST_CID; } +static s64 vhost_transport_stream_has_data(struct vsock_sock *vsk) +{ + /* vmci_transport doesn't allow half-closed socket on the host side. + * recv() on the host side returns EOF when the guest closes a + * connection, also if some data is still in the receive queue. + * + * In order to provide the same behaviour, we always return 0 + * (no data available) if the peer (guest) closed the connection. + */ + if (vsk->peer_shutdown == SHUTDOWN_MASK) + return 0; + + return virtio_transport_stream_has_data(vsk); +} + /* Callers that dereference the return value must hold vhost_vsock_mutex or the * RCU read lock. */ @@ -804,7 +819,7 @@ static struct virtio_transport vhost_transport = { .stream_enqueue = virtio_transport_stream_enqueue, .stream_dequeue = virtio_transport_stream_dequeue, - .stream_has_data = virtio_transport_stream_has_data, + .stream_has_data = vhost_transport_stream_has_data, .stream_has_space = virtio_transport_stream_has_space, .stream_rcvhiwat = virtio_transport_stream_rcvhiwat, .stream_is_active = virtio_transport_stream_is_active, -- 2.21.0
Michael S. Tsirkin
2019-Oct-11 14:19 UTC
[PATCH net 0/2] vsock: don't allow half-closed socket in the host transports
On Fri, Oct 11, 2019 at 03:07:56PM +0200, Stefano Garzarella wrote:> We are implementing a test suite for the VSOCK sockets and we discovered > that vmci_transport never allowed half-closed socket on the host side. > > As Jorgen explained [1] this is due to the implementation of VMCI. > > Since we want to have the same behaviour across all transports, this > series adds a section in the "Implementation notes" to exaplain this > behaviour, and changes the vhost_transport to behave the same way. > > [1] https://patchwork.ozlabs.org/cover/847998/#1831400Half closed sockets are very useful, and lots of applications use tricks to swap a vsock for a tcp socket, which might as a result break. If VMCI really cares it can implement an ioctl to allow applications to detect that half closed sockets aren't supported. It does not look like VMCI wants to bother (users do not read kernel implementation notes) so it does not really care. So why do we want to cripple other transports intentionally?> Stefano Garzarella (2): > vsock: add half-closed socket details in the implementation notes > vhost/vsock: don't allow half-closed socket in the host > > drivers/vhost/vsock.c | 17 ++++++++++++++++- > net/vmw_vsock/af_vsock.c | 4 ++++ > 2 files changed, 20 insertions(+), 1 deletion(-) > > -- > 2.21.0
Michael S. Tsirkin
2019-Oct-11 14:22 UTC
[PATCH net 1/2] vsock: add half-closed socket details in the implementation notes
On Fri, Oct 11, 2019 at 03:07:57PM +0200, Stefano Garzarella wrote:> vmci_transport never allowed half-closed socket on the host side. > Since we want to have the same behaviour across all transports, we > add a section in the "Implementation notes". > > Cc: Jorgen Hansen <jhansen at vmware.com> > Cc: Adit Ranadive <aditr at vmware.com> > Signed-off-by: Stefano Garzarella <sgarzare at redhat.com> > --- > net/vmw_vsock/af_vsock.c | 4 ++++ > 1 file changed, 4 insertions(+) > > diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c > index 2ab43b2bba31..27df57c2024b 100644 > --- a/net/vmw_vsock/af_vsock.c > +++ b/net/vmw_vsock/af_vsock.c > @@ -83,6 +83,10 @@ > * TCP_ESTABLISHED - connected > * TCP_CLOSING - disconnecting > * TCP_LISTEN - listening > + * > + * - Half-closed socket is supported only on the guest side. recv() on the host > + * side should return EOF when the guest closes a connection, also if some > + * data is still in the receive queue. > */ > > #include <linux/types.h>That's a great way to lose data in a way that's hard to debug. VMCI sockets connect to a hypervisor so there's tight control of what the hypervisor can do. But vhost vsocks connect to a fully fledged Linux, so you can't assume this is safe. And application authors do not read kernel source.> -- > 2.21.0
Michael S. Tsirkin
2019-Oct-11 14:26 UTC
[PATCH net 2/2] vhost/vsock: don't allow half-closed socket in the host
On Fri, Oct 11, 2019 at 03:07:58PM +0200, Stefano Garzarella wrote:> vmci_transport never allowed half-closed socket on the host side. > In order to provide the same behaviour, we changed the > vhost_transport_stream_has_data() to return 0 (no data available) > if the peer (guest) closed the connection. > > Signed-off-by: Stefano Garzarella <sgarzare at redhat.com>I don't think we should copy bugs like this. Applications don't actually depend on this VMCI limitation, in fact it looks like a working application can get broken by this. So this looks like a userspace visible ABI change which we can't really do. If it turns out some application cares, it can always fully close the connection. Or add an ioctl so the application can find out whether half close works.> --- > drivers/vhost/vsock.c | 17 ++++++++++++++++- > 1 file changed, 16 insertions(+), 1 deletion(-) > > diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c > index 9f57736fe15e..754120aa4478 100644 > --- a/drivers/vhost/vsock.c > +++ b/drivers/vhost/vsock.c > @@ -58,6 +58,21 @@ static u32 vhost_transport_get_local_cid(void) > return VHOST_VSOCK_DEFAULT_HOST_CID; > } > > +static s64 vhost_transport_stream_has_data(struct vsock_sock *vsk) > +{ > + /* vmci_transport doesn't allow half-closed socket on the host side. > + * recv() on the host side returns EOF when the guest closes a > + * connection, also if some data is still in the receive queue. > + * > + * In order to provide the same behaviour, we always return 0 > + * (no data available) if the peer (guest) closed the connection. > + */ > + if (vsk->peer_shutdown == SHUTDOWN_MASK) > + return 0; > + > + return virtio_transport_stream_has_data(vsk); > +} > + > /* Callers that dereference the return value must hold vhost_vsock_mutex or the > * RCU read lock. > */ > @@ -804,7 +819,7 @@ static struct virtio_transport vhost_transport = { > > .stream_enqueue = virtio_transport_stream_enqueue, > .stream_dequeue = virtio_transport_stream_dequeue, > - .stream_has_data = virtio_transport_stream_has_data, > + .stream_has_data = vhost_transport_stream_has_data, > .stream_has_space = virtio_transport_stream_has_space, > .stream_rcvhiwat = virtio_transport_stream_rcvhiwat, > .stream_is_active = virtio_transport_stream_is_active, > -- > 2.21.0
Stefano Garzarella
2019-Oct-11 14:34 UTC
[PATCH net 0/2] vsock: don't allow half-closed socket in the host transports
On Fri, Oct 11, 2019 at 10:19:13AM -0400, Michael S. Tsirkin wrote:> On Fri, Oct 11, 2019 at 03:07:56PM +0200, Stefano Garzarella wrote: > > We are implementing a test suite for the VSOCK sockets and we discovered > > that vmci_transport never allowed half-closed socket on the host side. > > > > As Jorgen explained [1] this is due to the implementation of VMCI. > > > > Since we want to have the same behaviour across all transports, this > > series adds a section in the "Implementation notes" to exaplain this > > behaviour, and changes the vhost_transport to behave the same way. > > > > [1] https://patchwork.ozlabs.org/cover/847998/#1831400 > > Half closed sockets are very useful, and lots of > applications use tricks to swap a vsock for a tcp socket, > which might as a result break.Got it!> > If VMCI really cares it can implement an ioctl to > allow applications to detect that half closed sockets aren't supported. > > It does not look like VMCI wants to bother (users do not read > kernel implementation notes) so it does not really care. > So why do we want to cripple other transports intentionally?The main reason is that we are developing the test suite and we noticed the miss match. Since we want to make sure that applications behave in the same way on different transports, we thought we would solve it that way. But what you are saying (also in the reply of the patches) is actually quite right. Not being publicized, applications do not expect this behavior, so please discard this series. My problem during the tests, was trying to figure out if half-closed sockets were supported or not, so as you say adding an IOCTL or maybe better a getsockopt() could solve the problem. What do you think? Thanks, Stefano
Reasonably Related Threads
- [PATCH net 1/2] vsock: add half-closed socket details in the implementation notes
- [PATCH net 0/2] vsock: don't allow half-closed socket in the host transports
- [PATCH net 0/2] vsock: don't allow half-closed socket in the host transports
- [PATCH v2] VSOCK: Don't call vsock_stream_has_data in atomic context
- [PATCH v2] VSOCK: Don't call vsock_stream_has_data in atomic context