qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* qemu-sockets: account for trailing \0 byte in unix socket pathname
@ 2021-08-30 22:54 Michael Tokarev
  2021-08-31 12:32 ` Marc-André Lureau
  2021-08-31 17:17 ` Michael Tokarev
  0 siblings, 2 replies; 8+ messages in thread
From: Michael Tokarev @ 2021-08-30 22:54 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Michael Tokarev, qemu-stable

Linux kernel can return size of af_unix socket to be
one byte larger than sockaddr_un structure - adding
the trailing zero byte.

Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
Fixes: 4cfd970ec188558daa6214f26203fe553fb1e01f (first in 6.1.0)
Cc: qemu-stable@nongnu.org

diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index f2f3676d1f..83926dc2bc 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -1345,8 +1345,9 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
     SocketAddress *addr;
     struct sockaddr_un *su = (struct sockaddr_un *)sa;
 
+    /* kernel might have added \0 terminator to non-abstract socket */
     assert(salen >= sizeof(su->sun_family) + 1 &&
-           salen <= sizeof(struct sockaddr_un));
+           salen <= sizeof(struct sockaddr_un) + su->sun_path[0] ? 1 : 0);
 
     addr = g_new0(SocketAddress, 1);
     addr->type = SOCKET_ADDRESS_TYPE_UNIX;


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: qemu-sockets: account for trailing \0 byte in unix socket pathname
  2021-08-30 22:54 qemu-sockets: account for trailing \0 byte in unix socket pathname Michael Tokarev
@ 2021-08-31 12:32 ` Marc-André Lureau
  2021-08-31 13:11   ` Daniel P. Berrangé
  2021-08-31 17:17 ` Michael Tokarev
  1 sibling, 1 reply; 8+ messages in thread
From: Marc-André Lureau @ 2021-08-31 12:32 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: QEMU, qemu-stable

[-- Attachment #1: Type: text/plain, Size: 1342 bytes --]

Hi

On Tue, Aug 31, 2021 at 3:00 AM Michael Tokarev <mjt@tls.msk.ru> wrote:

> Linux kernel can return size of af_unix socket to be
> one byte larger than sockaddr_un structure - adding
> the trailing zero byte.
>
> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> Fixes: 4cfd970ec188558daa6214f26203fe553fb1e01f (first in 6.1.0)
> Cc: qemu-stable@nongnu.org
>
> diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> index f2f3676d1f..83926dc2bc 100644
> --- a/util/qemu-sockets.c
> +++ b/util/qemu-sockets.c
> @@ -1345,8 +1345,9 @@ socket_sockaddr_to_address_unix(struct
> sockaddr_storage *sa,
>      SocketAddress *addr;
>      struct sockaddr_un *su = (struct sockaddr_un *)sa;
>
> +    /* kernel might have added \0 terminator to non-abstract socket */
>      assert(salen >= sizeof(su->sun_family) + 1 &&
> -           salen <= sizeof(struct sockaddr_un));
> +           salen <= sizeof(struct sockaddr_un) + su->sun_path[0] ? 1 : 0);
>
>
Looks right, but we may want to drop the upper bound check altogether. I
thought the path must always fit the sockaddr_un, but since that's not the
case it's only harmful here.

Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>

     addr = g_new0(SocketAddress, 1);
>      addr->type = SOCKET_ADDRESS_TYPE_UNIX;
>
>

-- 
Marc-André Lureau

[-- Attachment #2: Type: text/html, Size: 2171 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: qemu-sockets: account for trailing \0 byte in unix socket pathname
  2021-08-31 12:32 ` Marc-André Lureau
@ 2021-08-31 13:11   ` Daniel P. Berrangé
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel P. Berrangé @ 2021-08-31 13:11 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: Michael Tokarev, QEMU, qemu-stable

On Tue, Aug 31, 2021 at 04:32:36PM +0400, Marc-André Lureau wrote:
> Hi
> 
> On Tue, Aug 31, 2021 at 3:00 AM Michael Tokarev <mjt@tls.msk.ru> wrote:
> 
> > Linux kernel can return size of af_unix socket to be
> > one byte larger than sockaddr_un structure - adding
> > the trailing zero byte.
> >
> > Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> > Fixes: 4cfd970ec188558daa6214f26203fe553fb1e01f (first in 6.1.0)
> > Cc: qemu-stable@nongnu.org
> >
> > diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> > index f2f3676d1f..83926dc2bc 100644
> > --- a/util/qemu-sockets.c
> > +++ b/util/qemu-sockets.c
> > @@ -1345,8 +1345,9 @@ socket_sockaddr_to_address_unix(struct
> > sockaddr_storage *sa,
> >      SocketAddress *addr;
> >      struct sockaddr_un *su = (struct sockaddr_un *)sa;
> >
> > +    /* kernel might have added \0 terminator to non-abstract socket */
> >      assert(salen >= sizeof(su->sun_family) + 1 &&
> > -           salen <= sizeof(struct sockaddr_un));
> > +           salen <= sizeof(struct sockaddr_un) + su->sun_path[0] ? 1 : 0);
> >
> >
> Looks right, but we may want to drop the upper bound check altogether. I
> thought the path must always fit the sockaddr_un, but since that's not the
> case it's only harmful here.

Yeah, I don't think either old or new code are good here. The assert
is validating Linux semantics here, other platforms don't add the
extra NUL

Also later in the same method the string copy is dubious too:

    addr->u.q_unix.path = g_strndup(su->sun_path, sizeof(su->sun_path));

The man page says that to take account of non-portable semantics
wrt trailing NULs, the path length should be calculated using:

     strnlen(addr.sun_path, salen - offsetof(sockaddr_un, sun_path))


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: qemu-sockets: account for trailing \0 byte in unix socket pathname
  2021-08-30 22:54 qemu-sockets: account for trailing \0 byte in unix socket pathname Michael Tokarev
  2021-08-31 12:32 ` Marc-André Lureau
@ 2021-08-31 17:17 ` Michael Tokarev
  2021-08-31 17:22   ` Marc-André Lureau
  1 sibling, 1 reply; 8+ messages in thread
From: Michael Tokarev @ 2021-08-31 17:17 UTC (permalink / raw)
  To: qemu-devel; +Cc: Marc-André Lureau, Daniel P. Berrangé, qemu-stable

31.08.2021 01:54, Michael Tokarev wrote:
> Linux kernel can return size of af_unix socket to be
> one byte larger than sockaddr_un structure - adding
> the trailing zero byte.
> 
> Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> Fixes: 4cfd970ec188558daa6214f26203fe553fb1e01f (first in 6.1.0)
> Cc: qemu-stable@nongnu.org
> 
> diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> index f2f3676d1f..83926dc2bc 100644
> --- a/util/qemu-sockets.c
> +++ b/util/qemu-sockets.c
> @@ -1345,8 +1345,9 @@ socket_sockaddr_to_address_unix(struct sockaddr_storage *sa,
>       SocketAddress *addr;
>       struct sockaddr_un *su = (struct sockaddr_un *)sa;
>   
> +    /* kernel might have added \0 terminator to non-abstract socket */
>       assert(salen >= sizeof(su->sun_family) + 1 &&
> -           salen <= sizeof(struct sockaddr_un));
> +           salen <= sizeof(struct sockaddr_un) + su->sun_path[0] ? 1 : 0);
>   
>       addr = g_new0(SocketAddress, 1);
>       addr->type = SOCKET_ADDRESS_TYPE_UNIX;

Actually, this is not sufficient.

While this change fixes one issue (the famous trailing null byte \0),
the actual assertion failure occurs because salen = 2, ie, too SMALL,
not too large.

So it looks like libvirt provides an unnamed socket there, --
maybe from a socketpair(2)?

Hwell..

/mjt


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: qemu-sockets: account for trailing \0 byte in unix socket pathname
  2021-08-31 17:17 ` Michael Tokarev
@ 2021-08-31 17:22   ` Marc-André Lureau
  2021-08-31 17:38     ` Daniel P. Berrangé
  0 siblings, 1 reply; 8+ messages in thread
From: Marc-André Lureau @ 2021-08-31 17:22 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: Daniel P. Berrangé, qemu-devel, qemu-stable

[-- Attachment #1: Type: text/plain, Size: 1732 bytes --]

Hi

On Tue, Aug 31, 2021 at 9:17 PM Michael Tokarev <mjt@tls.msk.ru> wrote:

> 31.08.2021 01:54, Michael Tokarev wrote:
> > Linux kernel can return size of af_unix socket to be
> > one byte larger than sockaddr_un structure - adding
> > the trailing zero byte.
> >
> > Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> > Fixes: 4cfd970ec188558daa6214f26203fe553fb1e01f (first in 6.1.0)
> > Cc: qemu-stable@nongnu.org
> >
> > diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> > index f2f3676d1f..83926dc2bc 100644
> > --- a/util/qemu-sockets.c
> > +++ b/util/qemu-sockets.c
> > @@ -1345,8 +1345,9 @@ socket_sockaddr_to_address_unix(struct
> sockaddr_storage *sa,
> >       SocketAddress *addr;
> >       struct sockaddr_un *su = (struct sockaddr_un *)sa;
> >
> > +    /* kernel might have added \0 terminator to non-abstract socket */
> >       assert(salen >= sizeof(su->sun_family) + 1 &&
> > -           salen <= sizeof(struct sockaddr_un));
> > +           salen <= sizeof(struct sockaddr_un) + su->sun_path[0] ? 1 :
> 0);
> >
> >       addr = g_new0(SocketAddress, 1);
> >       addr->type = SOCKET_ADDRESS_TYPE_UNIX;
>
> Actually, this is not sufficient.
>
> While this change fixes one issue (the famous trailing null byte \0),
> the actual assertion failure occurs because salen = 2, ie, too SMALL,
> not too large.
>
> So it looks like libvirt provides an unnamed socket there, --
> maybe from a socketpair(2)?
>

Yes

Ok, I guess it should still check for salen >= sizeof(su->sun_family)

and then modify if (salen > sizeof(su->sun_family) && !su->sun_path[0]) {


> Hwell..
>

hmm, too bad we didn't catch it during RC!

(strange that it seems to hit Debian libvirt/virt-manager users and
apparently not on Fedora)

[-- Attachment #2: Type: text/html, Size: 2698 bytes --]

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: qemu-sockets: account for trailing \0 byte in unix socket pathname
  2021-08-31 17:22   ` Marc-André Lureau
@ 2021-08-31 17:38     ` Daniel P. Berrangé
  2021-08-31 17:47       ` Michael Tokarev
  0 siblings, 1 reply; 8+ messages in thread
From: Daniel P. Berrangé @ 2021-08-31 17:38 UTC (permalink / raw)
  To: Marc-André Lureau; +Cc: Michael Tokarev, qemu-devel, qemu-stable

On Tue, Aug 31, 2021 at 09:22:01PM +0400, Marc-André Lureau wrote:
> Hi
> 
> On Tue, Aug 31, 2021 at 9:17 PM Michael Tokarev <mjt@tls.msk.ru> wrote:
> 
> > 31.08.2021 01:54, Michael Tokarev wrote:
> > > Linux kernel can return size of af_unix socket to be
> > > one byte larger than sockaddr_un structure - adding
> > > the trailing zero byte.
> > >
> > > Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
> > > Fixes: 4cfd970ec188558daa6214f26203fe553fb1e01f (first in 6.1.0)
> > > Cc: qemu-stable@nongnu.org
> > >
> > > diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
> > > index f2f3676d1f..83926dc2bc 100644
> > > --- a/util/qemu-sockets.c
> > > +++ b/util/qemu-sockets.c
> > > @@ -1345,8 +1345,9 @@ socket_sockaddr_to_address_unix(struct
> > sockaddr_storage *sa,
> > >       SocketAddress *addr;
> > >       struct sockaddr_un *su = (struct sockaddr_un *)sa;
> > >
> > > +    /* kernel might have added \0 terminator to non-abstract socket */
> > >       assert(salen >= sizeof(su->sun_family) + 1 &&
> > > -           salen <= sizeof(struct sockaddr_un));
> > > +           salen <= sizeof(struct sockaddr_un) + su->sun_path[0] ? 1 :
> > 0);
> > >
> > >       addr = g_new0(SocketAddress, 1);
> > >       addr->type = SOCKET_ADDRESS_TYPE_UNIX;
> >
> > Actually, this is not sufficient.
> >
> > While this change fixes one issue (the famous trailing null byte \0),
> > the actual assertion failure occurs because salen = 2, ie, too SMALL,
> > not too large.
> >
> > So it looks like libvirt provides an unnamed socket there, --
> > maybe from a socketpair(2)?
> >
> 
> Yes

No, libvirt binds to a named socket path and passes in a pre-opened
FD for the listener socket. There shouldn't be any socketpair involved.


Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: qemu-sockets: account for trailing \0 byte in unix socket pathname
  2021-08-31 17:38     ` Daniel P. Berrangé
@ 2021-08-31 17:47       ` Michael Tokarev
  2021-08-31 17:51         ` Daniel P. Berrangé
  0 siblings, 1 reply; 8+ messages in thread
From: Michael Tokarev @ 2021-08-31 17:47 UTC (permalink / raw)
  To: Daniel P. Berrangé, Marc-André Lureau; +Cc: qemu-devel, qemu-stable

31.08.2021 20:38, Daniel P. Berrangé wrote:
...
>>> So it looks like libvirt provides an unnamed socket there, --
>>> maybe from a socketpair(2)?
>>>
>>
>> Yes
> 
> No, libvirt binds to a named socket path and passes in a pre-opened
> FD for the listener socket. There shouldn't be any socketpair involved.

Here's some more info from the original bugreport:

31.08.2021 00:20, dann frazier wrote:
 > Aha! It seems that the important difference is whether or not the
 > virt-manager GUI window for the VM is active. If it is active, the VM
 > crashes regardless of how it is started (virsh console start/clicking
 > "play" button). If the GUI is not active, the VM always works.
 >
 > With this knowledge I am able to confidently say that reverting
 > 4cfd970ec1 *does* reliably avoid the problem.

We'll try to figure out the calltrace, where this socket is coming from..

/mjt


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: qemu-sockets: account for trailing \0 byte in unix socket pathname
  2021-08-31 17:47       ` Michael Tokarev
@ 2021-08-31 17:51         ` Daniel P. Berrangé
  0 siblings, 0 replies; 8+ messages in thread
From: Daniel P. Berrangé @ 2021-08-31 17:51 UTC (permalink / raw)
  To: Michael Tokarev; +Cc: Marc-André Lureau, qemu-devel, qemu-stable

On Tue, Aug 31, 2021 at 08:47:43PM +0300, Michael Tokarev wrote:
> 31.08.2021 20:38, Daniel P. Berrangé wrote:
> ...
> > > > So it looks like libvirt provides an unnamed socket there, --
> > > > maybe from a socketpair(2)?
> > > > 
> > > 
> > > Yes
> > 
> > No, libvirt binds to a named socket path and passes in a pre-opened
> > FD for the listener socket. There shouldn't be any socketpair involved.
> 
> Here's some more info from the original bugreport:
> 
> 31.08.2021 00:20, dann frazier wrote:
> > Aha! It seems that the important difference is whether or not the
> > virt-manager GUI window for the VM is active. If it is active, the VM
> > crashes regardless of how it is started (virsh console start/clicking
> > "play" button). If the GUI is not active, the VM always works.
> >
> > With this knowledge I am able to confidently say that reverting
> > 4cfd970ec1 *does* reliably avoid the problem.
> 
> We'll try to figure out the calltrace, where this socket is coming from..

Oh, it is probably from the graphical console connection to SPICE or VNC.
For those virt-manager will pass in a socket creted with socketpair()
via libvirt, in order to bypass the need for authentication when running
locally.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|



^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2021-08-31 17:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-30 22:54 qemu-sockets: account for trailing \0 byte in unix socket pathname Michael Tokarev
2021-08-31 12:32 ` Marc-André Lureau
2021-08-31 13:11   ` Daniel P. Berrangé
2021-08-31 17:17 ` Michael Tokarev
2021-08-31 17:22   ` Marc-André Lureau
2021-08-31 17:38     ` Daniel P. Berrangé
2021-08-31 17:47       ` Michael Tokarev
2021-08-31 17:51         ` Daniel P. Berrangé

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).