mirror of
https://gitlab.uni-freiburg.de/opensourcevdi/spice
synced 2026-08-06 15:34:29 +00:00
sys-socket: Add spice_socketpair helper that makes sockets FD_CLOEXEC
Non-CLOEXEC descriptors leak on QEMU cpr-exec migration. QEMU has all of its internal sockets CLOEXEC'd, and expects the external libraries to do the same. Signed-off-by: Polina Vishneva <polina.vishneva@virtuozzo.com> Acked-by: Frediano Ziglio <freddy77@gmail.com>
This commit is contained in:
parent
bf1be3d08e
commit
e45861f995
1
AUTHORS
1
AUTHORS
@ -98,5 +98,6 @@ Patches also contributed by
|
||||
Daniel Kahn Gillmor <dkg@fifthhorseman.net>
|
||||
Nicholas Vinson <nvinson234@gmail.com>
|
||||
yanlonglong <yanlonglong@kylinos.cn>
|
||||
Polina Vishneva <polina.vishneva@virtuozzo.com>
|
||||
|
||||
....send patches to get your name here...
|
||||
|
||||
@ -85,7 +85,7 @@ Dispatcher::Dispatcher(uint32_t max_message_type):
|
||||
{
|
||||
int channels[2];
|
||||
|
||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, channels) == -1) {
|
||||
if (socket_newpair(SOCK_STREAM, 0, channels) == -1) {
|
||||
spice_error("socketpair failed %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -34,7 +34,40 @@
|
||||
|
||||
#include "sys-socket.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef _WIN32
|
||||
int socket_newpair(int type, int protocol, int sv[2])
|
||||
{
|
||||
const int domain = AF_LOCAL;
|
||||
int ret;
|
||||
int flags;
|
||||
|
||||
#ifdef SOCK_CLOEXEC
|
||||
ret = socketpair(domain, type | SOCK_CLOEXEC, protocol, sv);
|
||||
if (!(ret == -1 && errno == EINVAL)) {
|
||||
/* Failure isn't caused by the lack of SOCK_CLOEXEC support
|
||||
* in the currently running kernel */
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = socketpair(domain, type, protocol, sv);
|
||||
if (ret == -1) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
flags = fcntl(sv[0], F_GETFD);
|
||||
if (flags != -1) {
|
||||
fcntl(sv[0], F_SETFD, flags | FD_CLOEXEC);
|
||||
}
|
||||
|
||||
flags = fcntl(sv[1], F_GETFD);
|
||||
if (flags != -1) {
|
||||
fcntl(sv[1], F_SETFD, flags | FD_CLOEXEC);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
// Map Windows socket errors to standard C ones
|
||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms740668(v=vs.85).aspx
|
||||
void socket_win32_set_errno(void)
|
||||
@ -208,6 +241,11 @@ SPICE_CONSTRUCTOR_FUNC(socket_win32_init)
|
||||
WSAStartup(MAKEWORD(2, 2), &wsaData);
|
||||
}
|
||||
|
||||
static inline SOCKET socket_inet_noinherit(int type)
|
||||
{
|
||||
return WSASocketW(AF_INET, type, 0, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT);
|
||||
}
|
||||
|
||||
int socket_newpair(int type, int protocol, int sv[2])
|
||||
{
|
||||
struct sockaddr_in sa, sa2;
|
||||
@ -219,14 +257,14 @@ int socket_newpair(int type, int protocol, int sv[2])
|
||||
}
|
||||
|
||||
/* create a listener */
|
||||
s = socket(AF_INET, type, 0);
|
||||
s = socket_inet_noinherit(type);
|
||||
if (s == INVALID_SOCKET) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
pairs[1] = INVALID_SOCKET;
|
||||
|
||||
pairs[0] = socket(AF_INET, type, 0);
|
||||
pairs[0] = socket_inet_noinherit(type);
|
||||
if (pairs[0] == INVALID_SOCKET) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -21,6 +21,10 @@
|
||||
#ifndef RED_SYS_SOCKET_H_
|
||||
#define RED_SYS_SOCKET_H_
|
||||
|
||||
#include <spice/macros.h>
|
||||
|
||||
SPICE_BEGIN_DECLS
|
||||
|
||||
#ifndef _WIN32
|
||||
# include <sys/socket.h>
|
||||
|
||||
@ -32,9 +36,6 @@
|
||||
#else
|
||||
# include <winsock2.h>
|
||||
# include <windows.h>
|
||||
# include <spice/macros.h>
|
||||
|
||||
SPICE_BEGIN_DECLS
|
||||
|
||||
typedef int socklen_t;
|
||||
|
||||
@ -139,15 +140,15 @@ socket_accept(int sock, struct sockaddr *addr, int *addrlen)
|
||||
#undef accept
|
||||
#define accept socket_accept
|
||||
|
||||
int socket_newpair(int type, int protocol, int sv[2]);
|
||||
#define socketpair(family, type, protocol, sv) socket_newpair(type, protocol, sv)
|
||||
|
||||
SPICE_END_DECLS
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(SO_NOSIGPIPE) && defined(__APPLE__)
|
||||
#define MSG_NOSIGNAL 0
|
||||
#endif
|
||||
|
||||
// Ensures FD_CLOEXEC flag is set if available, in the best way available
|
||||
int socket_newpair(int type, int protocol, int sv[2]);
|
||||
|
||||
SPICE_END_DECLS
|
||||
|
||||
#endif // RED_SYS_SOCKET_H_
|
||||
|
||||
@ -183,7 +183,7 @@ static void timeout_watch_count(void *opaque)
|
||||
static RedStream *create_dummy_stream(SpiceServer *server, int *p_socket)
|
||||
{
|
||||
int sv[2];
|
||||
g_assert_cmpint(socketpair(AF_LOCAL, SOCK_STREAM, 0, sv), ==, 0);
|
||||
g_assert_cmpint(socket_newpair(SOCK_STREAM, 0, sv), ==, 0);
|
||||
if (p_socket) {
|
||||
*p_socket = sv[1];
|
||||
}
|
||||
|
||||
@ -77,7 +77,7 @@ static void server_leaks(void)
|
||||
#endif
|
||||
g_test_expect_message(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
|
||||
"*SSL_accept failed*");
|
||||
g_assert_cmpint(socketpair(AF_LOCAL, SOCK_STREAM, 0, sv), ==, 0);
|
||||
g_assert_cmpint(socket_newpair(SOCK_STREAM, 0, sv), ==, 0);
|
||||
socket_close(sv[1]);
|
||||
result = spice_server_add_ssl_client(server, sv[0], 1);
|
||||
g_assert_cmpint(result, ==, -1);
|
||||
|
||||
@ -32,6 +32,7 @@
|
||||
|
||||
#include "test-glib-compat.h"
|
||||
#include "basic-event-loop.h"
|
||||
#include "sys-socket.h"
|
||||
|
||||
#include <spice/start-packed.h>
|
||||
typedef struct SPICE_ATTR_PACKED SpiceInitialMessage {
|
||||
@ -602,7 +603,7 @@ setup_thread(void)
|
||||
test_num, len, data->mechname, len, data->line);
|
||||
|
||||
int sv[2];
|
||||
g_assert_cmpint(socketpair(AF_LOCAL, SOCK_STREAM, 0, sv), ==, 0);
|
||||
g_assert_cmpint(socket_newpair(SOCK_STREAM, 0, sv), ==, 0);
|
||||
|
||||
g_assert(spice_server_add_client(server, sv[0], 0) == 0);
|
||||
|
||||
|
||||
@ -82,7 +82,7 @@ static void test_smartcard_teardown(TestFixture *fixture, gconstpointer user_dat
|
||||
static RedStream *create_dummy_stream(SpiceServer *server, int *p_socket)
|
||||
{
|
||||
int sv[2];
|
||||
g_assert_cmpint(socketpair(AF_LOCAL, SOCK_STREAM, 0, sv), ==, 0);
|
||||
g_assert_cmpint(socket_newpair(SOCK_STREAM, 0, sv), ==, 0);
|
||||
if (p_socket) {
|
||||
*p_socket = sv[1];
|
||||
}
|
||||
|
||||
@ -106,7 +106,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
spice_return_val_if_fail(server_init() == 0, -1);
|
||||
|
||||
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv) == -1) {
|
||||
if (socket_newpair(SOCK_STREAM, 0, sv) == -1) {
|
||||
spice_error("socketpair failed %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user