* [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
@ 2015-07-22 13:07 Richard W.M. Jones
2015-07-22 13:07 ` Richard W.M. Jones
0 siblings, 1 reply; 8+ messages in thread
From: Richard W.M. Jones @ 2015-07-22 13:07 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, jcody, qemu-block
v2:
I fixed several mistakes in the commit message. The code change
is the same as before.
Rich.
^ permalink raw reply [flat|nested] 8+ messages in thread
* [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
2015-07-22 13:07 [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno Richard W.M. Jones
@ 2015-07-22 13:07 ` Richard W.M. Jones
2015-07-22 13:10 ` Daniel P. Berrange
2015-07-22 13:17 ` Jeff Cody
0 siblings, 2 replies; 8+ messages in thread
From: Richard W.M. Jones @ 2015-07-22 13:07 UTC (permalink / raw)
To: qemu-devel; +Cc: kwolf, jcody, qemu-block
On some (but not all) systems:
$ qemu-img create -f qcow2 overlay -b ssh://xen/
Segmentation fault
It turns out this happens when inet_connect returns -1 in the
following code, but errno == 0.
s->sock = inet_connect(s->hostport, errp);
if (s->sock < 0) {
ret = -errno;
goto err;
}
In the test case above, no host called "xen" exists, so getaddrinfo fails.
On Fedora 22, getaddrinfo happens to set errno = ENOENT (although it
is *not* documented to do that), so it doesn't segfault.
On RHEL 7, errno is not set by the failing getaddrinfo, so ret =
-errno = 0, so the caller doesn't know there was an error and
continues with a half-initialized BDRVSSHState struct, and everything
goes south from there, eventually resulting in a segfault.
Fix this by setting ret to -EINVAL. The real error is saved in the
Error** errp struct, so it is printed correctly:
$ ./qemu-img create -f qcow2 overlay -b ssh://xen/
qemu-img: overlay: address resolution failed for xen:22: No address associated with hostname
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Reported-by: Jun Li
BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1147343
---
block/ssh.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/ssh.c b/block/ssh.c
index aebb18c..8d4dc2a 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -563,7 +563,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
/* Open the socket and connect. */
s->sock = inet_connect(s->hostport, errp);
if (s->sock < 0) {
- ret = -errno;
+ ret = -EINVAL;
goto err;
}
--
2.4.3
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
2015-07-22 13:07 ` Richard W.M. Jones
@ 2015-07-22 13:10 ` Daniel P. Berrange
2015-07-22 13:17 ` Richard W.M. Jones
2015-07-22 13:24 ` Kevin Wolf
2015-07-22 13:17 ` Jeff Cody
1 sibling, 2 replies; 8+ messages in thread
From: Daniel P. Berrange @ 2015-07-22 13:10 UTC (permalink / raw)
To: Richard W.M. Jones; +Cc: kwolf, jcody, qemu-devel, qemu-block
On Wed, Jul 22, 2015 at 02:07:22PM +0100, Richard W.M. Jones wrote:
> On some (but not all) systems:
>
> $ qemu-img create -f qcow2 overlay -b ssh://xen/
> Segmentation fault
>
> It turns out this happens when inet_connect returns -1 in the
> following code, but errno == 0.
>
> s->sock = inet_connect(s->hostport, errp);
> if (s->sock < 0) {
> ret = -errno;
> goto err;
> }
>
> In the test case above, no host called "xen" exists, so getaddrinfo fails.
>
> On Fedora 22, getaddrinfo happens to set errno = ENOENT (although it
> is *not* documented to do that), so it doesn't segfault.
>
> On RHEL 7, errno is not set by the failing getaddrinfo, so ret =
> -errno = 0, so the caller doesn't know there was an error and
> continues with a half-initialized BDRVSSHState struct, and everything
> goes south from there, eventually resulting in a segfault.
>
> Fix this by setting ret to -EINVAL. The real error is saved in the
> Error** errp struct, so it is printed correctly:
>
> $ ./qemu-img create -f qcow2 overlay -b ssh://xen/
> qemu-img: overlay: address resolution failed for xen:22: No address associated with hostname
>
> Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
> Reported-by: Jun Li
> BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1147343
> ---
> block/ssh.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/block/ssh.c b/block/ssh.c
> index aebb18c..8d4dc2a 100644
> --- a/block/ssh.c
> +++ b/block/ssh.c
> @@ -563,7 +563,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
> /* Open the socket and connect. */
> s->sock = inet_connect(s->hostport, errp);
> if (s->sock < 0) {
> - ret = -errno;
> + ret = -EINVAL;
> goto err;
There are a reasonable number of other uses of inet_connect() in QEMU,
so can't we fix inet_connect() itself to set EINVAL in the error case
instead of just fixing one caller.
Regards,
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
2015-07-22 13:10 ` Daniel P. Berrange
@ 2015-07-22 13:17 ` Richard W.M. Jones
2015-07-22 13:24 ` Kevin Wolf
1 sibling, 0 replies; 8+ messages in thread
From: Richard W.M. Jones @ 2015-07-22 13:17 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: kwolf, jcody, qemu-devel, qemu-block
On Wed, Jul 22, 2015 at 02:10:51PM +0100, Daniel P. Berrange wrote:
> There are a reasonable number of other uses of inet_connect() in QEMU,
> so can't we fix inet_connect() itself to set EINVAL in the error case
> instead of just fixing one caller.
The only users I can find are block/nbd.c and block/sheepdog.c, and
neither of those is expecting errno to be set. So I think my use of
errno in block/ssh.c was flat out wrong, although it happened to work
most of the time.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
2015-07-22 13:07 ` Richard W.M. Jones
2015-07-22 13:10 ` Daniel P. Berrange
@ 2015-07-22 13:17 ` Jeff Cody
2015-07-22 13:22 ` Richard W.M. Jones
1 sibling, 1 reply; 8+ messages in thread
From: Jeff Cody @ 2015-07-22 13:17 UTC (permalink / raw)
To: Richard W.M. Jones; +Cc: kwolf, qemu-devel, qemu-block
On Wed, Jul 22, 2015 at 02:07:22PM +0100, Richard W.M. Jones wrote:
> On some (but not all) systems:
>
> $ qemu-img create -f qcow2 overlay -b ssh://xen/
> Segmentation fault
>
> It turns out this happens when inet_connect returns -1 in the
> following code, but errno == 0.
>
> s->sock = inet_connect(s->hostport, errp);
> if (s->sock < 0) {
> ret = -errno;
> goto err;
> }
>
> In the test case above, no host called "xen" exists, so getaddrinfo fails.
>
> On Fedora 22, getaddrinfo happens to set errno = ENOENT (although it
> is *not* documented to do that), so it doesn't segfault.
>
> On RHEL 7, errno is not set by the failing getaddrinfo, so ret =
> -errno = 0, so the caller doesn't know there was an error and
> continues with a half-initialized BDRVSSHState struct, and everything
> goes south from there, eventually resulting in a segfault.
>
> Fix this by setting ret to -EINVAL. The real error is saved in the
> Error** errp struct, so it is printed correctly:
>
> $ ./qemu-img create -f qcow2 overlay -b ssh://xen/
> qemu-img: overlay: address resolution failed for xen:22: No address associated with hostname
>
> Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
> Reported-by: Jun Li
> BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1147343
> ---
> block/ssh.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/block/ssh.c b/block/ssh.c
> index aebb18c..8d4dc2a 100644
> --- a/block/ssh.c
> +++ b/block/ssh.c
> @@ -563,7 +563,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
> /* Open the socket and connect. */
> s->sock = inet_connect(s->hostport, errp);
> if (s->sock < 0) {
> - ret = -errno;
> + ret = -EINVAL;
Both nbd and sheepdog handle it in a similar fashion (i.e. not relying
on errno being set on inet_connect failure). However, both nbd and
sheepdog use -EIO as the error return, and I think that makes more
sense. What do you think?
> goto err;
> }
>
> --
> 2.4.3
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
2015-07-22 13:17 ` Jeff Cody
@ 2015-07-22 13:22 ` Richard W.M. Jones
2015-07-22 13:26 ` Jeff Cody
0 siblings, 1 reply; 8+ messages in thread
From: Richard W.M. Jones @ 2015-07-22 13:22 UTC (permalink / raw)
To: Jeff Cody; +Cc: kwolf, qemu-devel, qemu-block
On Wed, Jul 22, 2015 at 09:17:49AM -0400, Jeff Cody wrote:
> Both nbd and sheepdog handle it in a similar fashion (i.e. not relying
> on errno being set on inet_connect failure). However, both nbd and
> sheepdog use -EIO as the error return, and I think that makes more
> sense. What do you think?
If you prefer -- I don't mind as long as it doesn't segfault :-)
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages. http://libguestfs.org
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
2015-07-22 13:10 ` Daniel P. Berrange
2015-07-22 13:17 ` Richard W.M. Jones
@ 2015-07-22 13:24 ` Kevin Wolf
1 sibling, 0 replies; 8+ messages in thread
From: Kevin Wolf @ 2015-07-22 13:24 UTC (permalink / raw)
To: Daniel P. Berrange; +Cc: jcody, Richard W.M. Jones, qemu-block, qemu-devel
Am 22.07.2015 um 15:10 hat Daniel P. Berrange geschrieben:
> On Wed, Jul 22, 2015 at 02:07:22PM +0100, Richard W.M. Jones wrote:
> > On some (but not all) systems:
> >
> > $ qemu-img create -f qcow2 overlay -b ssh://xen/
> > Segmentation fault
> >
> > It turns out this happens when inet_connect returns -1 in the
> > following code, but errno == 0.
> >
> > s->sock = inet_connect(s->hostport, errp);
> > if (s->sock < 0) {
> > ret = -errno;
> > goto err;
> > }
> >
> > In the test case above, no host called "xen" exists, so getaddrinfo fails.
> >
> > On Fedora 22, getaddrinfo happens to set errno = ENOENT (although it
> > is *not* documented to do that), so it doesn't segfault.
> >
> > On RHEL 7, errno is not set by the failing getaddrinfo, so ret =
> > -errno = 0, so the caller doesn't know there was an error and
> > continues with a half-initialized BDRVSSHState struct, and everything
> > goes south from there, eventually resulting in a segfault.
> >
> > Fix this by setting ret to -EINVAL. The real error is saved in the
> > Error** errp struct, so it is printed correctly:
> >
> > $ ./qemu-img create -f qcow2 overlay -b ssh://xen/
> > qemu-img: overlay: address resolution failed for xen:22: No address associated with hostname
> >
> > Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
> > Reported-by: Jun Li
> > BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1147343
> > ---
> > block/ssh.c | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/block/ssh.c b/block/ssh.c
> > index aebb18c..8d4dc2a 100644
> > --- a/block/ssh.c
> > +++ b/block/ssh.c
> > @@ -563,7 +563,7 @@ static int connect_to_ssh(BDRVSSHState *s, QDict *options,
> > /* Open the socket and connect. */
> > s->sock = inet_connect(s->hostport, errp);
> > if (s->sock < 0) {
> > - ret = -errno;
> > + ret = -EINVAL;
> > goto err;
>
> There are a reasonable number of other uses of inet_connect() in QEMU,
> so can't we fix inet_connect() itself to set EINVAL in the error case
> instead of just fixing one caller.
None of the other callers try to use errno, which isn't even documented
as part of the inet_connect() interface. So I think setting errno inside
inet_connect() would be wrong.
If we were to change anything, we might consider returning -EINVAL
instead of -1, though I'm not sure how useful that change would be. We
would still have to fix this call in the ssh block driver.
Kevin
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno.
2015-07-22 13:22 ` Richard W.M. Jones
@ 2015-07-22 13:26 ` Jeff Cody
0 siblings, 0 replies; 8+ messages in thread
From: Jeff Cody @ 2015-07-22 13:26 UTC (permalink / raw)
To: Richard W.M. Jones; +Cc: kwolf, qemu-devel, qemu-block
On Wed, Jul 22, 2015 at 02:22:18PM +0100, Richard W.M. Jones wrote:
> On Wed, Jul 22, 2015 at 09:17:49AM -0400, Jeff Cody wrote:
> > Both nbd and sheepdog handle it in a similar fashion (i.e. not relying
> > on errno being set on inet_connect failure). However, both nbd and
> > sheepdog use -EIO as the error return, and I think that makes more
> > sense. What do you think?
>
> If you prefer -- I don't mind as long as it doesn't segfault :-)
>
I think I would - mainly for consistency, but also because -EIO better
describes all the various failures that may occur in inet_connect().
Thanks!
Jeff
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-07-22 13:26 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-07-22 13:07 [Qemu-devel] [PATCH v2] block/ssh: Avoid segfault if inet_connect doesn't set errno Richard W.M. Jones
2015-07-22 13:07 ` Richard W.M. Jones
2015-07-22 13:10 ` Daniel P. Berrange
2015-07-22 13:17 ` Richard W.M. Jones
2015-07-22 13:24 ` Kevin Wolf
2015-07-22 13:17 ` Jeff Cody
2015-07-22 13:22 ` Richard W.M. Jones
2015-07-22 13:26 ` Jeff Cody
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).