• R
    block/ssh: Avoid segfault if inet_connect doesn't set errno. · 325e3904
    Richard W.M. Jones 提交于
    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 -EIO (same as block/nbd.c and
    block/sheepdog.c).  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: NRichard W.M. Jones <rjones@redhat.com>
    Reported-by: Jun Li
    BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1147343Signed-off-by: NJeff Cody <jcody@redhat.com>
    325e3904
ssh.c 30.8 KB