All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Daniel P. Berrangé" <berrange@redhat.com>
To: marcandre.lureau@redhat.com
Cc: qemu-devel@nongnu.org, Stefan Weil <sw@weilnetz.de>,
	Gerd Hoffmann <kraxel@redhat.com>
Subject: Re: [PATCH 1/3] win32: add qemu_close_to_socket()
Date: Mon, 20 Mar 2023 12:10:07 +0000	[thread overview]
Message-ID: <ZBhNH11aUoRTWHD1@redhat.com> (raw)
In-Reply-To: <20230320111412.1516419-2-marcandre.lureau@redhat.com>

On Mon, Mar 20, 2023 at 03:14:10PM +0400, marcandre.lureau@redhat.com wrote:
> From: Marc-André Lureau <marcandre.lureau@redhat.com>
> 
> Close the given file descriptor, but returns the underlying SOCKET.
> 
> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
> ---
>  include/sysemu/os-win32.h |  1 +
>  util/oslib-win32.c        | 68 +++++++++++++++++++++------------------
>  2 files changed, 38 insertions(+), 31 deletions(-)
> 
> diff --git a/include/sysemu/os-win32.h b/include/sysemu/os-win32.h
> index e2849f88ab..95cba6b284 100644
> --- a/include/sysemu/os-win32.h
> +++ b/include/sysemu/os-win32.h
> @@ -174,6 +174,7 @@ bool qemu_socket_unselect(int sockfd, Error **errp);
>  /* We wrap all the sockets functions so that we can
>   * set errno based on WSAGetLastError()
>   */
> +SOCKET qemu_close_to_socket(int fd);

Took me a while to understand what this function is actually doing.

IIUC, it assumes 'fd' was previously created by _open_osfhandle,
and close this OSF handle, leaving the SOCKET still open.

Could we call this one  'qemu_close_socket_osfhandle' and also
add a comment describing what this does.

>  
>  #undef close
>  #define close qemu_close_wrap
> diff --git a/util/oslib-win32.c b/util/oslib-win32.c
> index 16f8a67f7e..e37276b414 100644
> --- a/util/oslib-win32.c
> +++ b/util/oslib-win32.c
> @@ -479,52 +479,58 @@ int qemu_bind_wrap(int sockfd, const struct sockaddr *addr,
>      return ret;
>  }
>  
> -
>  #undef close
> -int qemu_close_wrap(int fd)
> +SOCKET qemu_close_to_socket(int fd)
>  {
> -    int ret;
> +    SOCKET s = _get_osfhandle(fd);
>      DWORD flags = 0;
> -    SOCKET s = INVALID_SOCKET;
> -
> -    if (fd_is_socket(fd)) {
> -        s = _get_osfhandle(fd);
>  
> -        /*
> -         * If we were to just call _close on the descriptor, it would close the
> -         * HANDLE, but it wouldn't free any of the resources associated to the
> -         * SOCKET, and we can't call _close after calling closesocket, because
> -         * closesocket has already closed the HANDLE, and _close would attempt to
> -         * close the HANDLE again, resulting in a double free. We can however
> -         * protect the HANDLE from actually being closed long enough to close the
> -         * file descriptor, then close the socket itself.
> -         */
> -        if (!GetHandleInformation((HANDLE)s, &flags)) {
> -            errno = EACCES;
> -            return -1;
> -        }
> -
> -        if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) {
> -            errno = EACCES;
> -            return -1;
> -        }
> +    /*
> +     * If we were to just call _close on the descriptor, it would close the
> +     * HANDLE, but it wouldn't free any of the resources associated to the
> +     * SOCKET, and we can't call _close after calling closesocket, because
> +     * closesocket has already closed the HANDLE, and _close would attempt to
> +     * close the HANDLE again, resulting in a double free. We can however
> +     * protect the HANDLE from actually being closed long enough to close the
> +     * file descriptor, then close the socket itself.
> +     */
> +    if (!GetHandleInformation((HANDLE)s, &flags)) {
> +        errno = EACCES;
> +        return INVALID_SOCKET;
>      }
>  
> -    ret = close(fd);
> -
> -    if (s != INVALID_SOCKET && !SetHandleInformation((HANDLE)s, flags, flags)) {
> +    if (!SetHandleInformation((HANDLE)s, HANDLE_FLAG_PROTECT_FROM_CLOSE, HANDLE_FLAG_PROTECT_FROM_CLOSE)) {
>          errno = EACCES;
> -        return -1;
> +        return INVALID_SOCKET;
>      }
>  
>      /*
>       * close() returns EBADF since we PROTECT_FROM_CLOSE the underlying handle,
>       * but the FD is actually freed
>       */
> -    if (ret < 0 && (s == INVALID_SOCKET || errno != EBADF)) {
> -        return ret;
> +    if (close(fd) < 0 && errno != EBADF) {
> +        return INVALID_SOCKET;
> +    }
> +
> +    if (!SetHandleInformation((HANDLE)s, flags, flags)) {
> +        errno = EACCES;
> +        return INVALID_SOCKET;
> +    }
> +
> +    return s;
> +}
> +
> +int qemu_close_wrap(int fd)
> +{
> +    SOCKET s = INVALID_SOCKET;
> +    int ret = -1;
> +
> +    if (!fd_is_socket(fd)) {
> +        return close(fd);
>      }
>  
> +    s = qemu_close_to_socket(fd);
> +
>      if (s != INVALID_SOCKET) {
>          ret = closesocket(s);
>          if (ret < 0) {
> -- 
> 2.39.2
> 

With 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 :|



  reply	other threads:[~2023-03-20 12:10 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-20 11:14 [PATCH 0/3] Fix Spice regression on win32 marcandre.lureau
2023-03-20 11:14 ` [PATCH 1/3] win32: add qemu_close_to_socket() marcandre.lureau
2023-03-20 12:10   ` Daniel P. Berrangé [this message]
2023-03-20 11:14 ` [PATCH 2/3] ui/spice: fix SOCKET handling regression marcandre.lureau
2023-03-20 12:10   ` Daniel P. Berrangé
2023-03-20 11:14 ` [PATCH 3/3] ui/dbus: fix passing SOCKET to GSocket API & leak marcandre.lureau
2023-03-20 12:17   ` Daniel P. Berrangé

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ZBhNH11aUoRTWHD1@redhat.com \
    --to=berrange@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=marcandre.lureau@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=sw@weilnetz.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.