Merge qio 2010/01/24

Fixes accidental deletion of VNC server UNIX listener socket
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABCAAGBQJcSa6LAAoJEL6G67QVEE/fkpkP/A79ZN4Mb3i5WTHYBYbzsicJ
 nqngWLh9m8qkuSgVFVzaFKtV/U4idHdFwt7f2fsboUnhVmOugE4ArDdzSqYVWNky
 tz/3UyfskZaNH6HtxuNhc1hyFN+zVPIw+0phQF8O2cQ6MVMufOYSocLcxrVF0436
 FqLoPjhLdFphJGBWxCRrXDLYu5BOWoupvuDGV7gRtMfvGi5OWiWhAEgewYPn9zUx
 lGdxCMbh/m+XKYcro8hiCJHnP7SdGrpMl3ZZh0QdTORangNObt8HSSpmdzaf4ueO
 NOv7rRVhhjvEXDLQguFpQAlt3ewjZ2V72Sdz4sM7WvNDpsYZlLXhSjUdHo1xbqVl
 PcB4GX8NYbv9idEZGfnvO/C6JrRfcWm8cbN8vs5sMTfSF8KqK7A4ISAJtqQE3r85
 y4Mtix5elSNwmCOZIwG6NovQOuK92iaFItPz9lzScSuXhRnR6GC2D03U/e54wDxw
 TRpoB8nL3hB4KFJEMNkdHS3RAuxuZcl1kz2yio+wPeI0Edm4aB+Y/FxlGw+Fs+kz
 rPH++pMbod6ZcDCc8PbzS1Th38pzPxYm4Rcbyw+YWz2nbjlz+kz4EVi2esg3fQIl
 TGB8vOyNYwq/cTaMwxqklK1SoB+sTHWZJKNuiSvyY2ZYNmUcMo/Hgb/I2QTzEqGS
 vnLp59vcidv73daZw/KT
 =Crcm
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/berrange/tags/qio-next-pull-request' into staging

Merge qio 2010/01/24

Fixes accidental deletion of VNC server UNIX listener socket

# gpg: Signature made Thu 24 Jan 2019 12:24:43 GMT
# gpg:                using RSA key BE86EBB415104FDF
# gpg: Good signature from "Daniel P. Berrange <dan@berrange.com>"
# gpg:                 aka "Daniel P. Berrange <berrange@redhat.com>"
# Primary key fingerprint: DAF3 A6FD B26B 6291 2D0E  8E3F BE86 EBB4 1510 4FDF

* remotes/berrange/tags/qio-next-pull-request:
  io: ensure UNIX client doesn't unlink server socket

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-01-25 09:26:33 +00:00
commit feff020891
2 changed files with 80 additions and 25 deletions

View File

@ -688,10 +688,13 @@ qio_channel_socket_close(QIOChannel *ioc,
int rc = 0;
if (sioc->fd != -1) {
SocketAddress *addr = socket_local_address(sioc->fd, errp);
#ifdef WIN32
WSAEventSelect(sioc->fd, NULL, 0);
#endif
if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_LISTEN)) {
socket_listen_cleanup(sioc->fd, errp);
}
if (closesocket(sioc->fd) < 0) {
sioc->fd = -1;
error_setg_errno(errp, errno,
@ -699,20 +702,6 @@ qio_channel_socket_close(QIOChannel *ioc,
return -1;
}
sioc->fd = -1;
if (addr && addr->type == SOCKET_ADDRESS_TYPE_UNIX
&& addr->u.q_unix.path) {
if (unlink(addr->u.q_unix.path) < 0 && errno != ENOENT) {
error_setg_errno(errp, errno,
"Failed to unlink socket %s",
addr->u.q_unix.path);
rc = -1;
}
}
if (addr) {
qapi_free_SocketAddress(addr);
}
}
return rc;
}

View File

@ -49,6 +49,7 @@ static void test_io_channel_set_socket_bufs(QIOChannel *src,
static void test_io_channel_setup_sync(SocketAddress *listen_addr,
SocketAddress *connect_addr,
QIOChannel **srv,
QIOChannel **src,
QIOChannel **dst)
{
@ -78,7 +79,7 @@ static void test_io_channel_setup_sync(SocketAddress *listen_addr,
test_io_channel_set_socket_bufs(*src, *dst);
object_unref(OBJECT(lioc));
*srv = QIO_CHANNEL(lioc);
}
@ -99,6 +100,7 @@ static void test_io_channel_complete(QIOTask *task,
static void test_io_channel_setup_async(SocketAddress *listen_addr,
SocketAddress *connect_addr,
QIOChannel **srv,
QIOChannel **src,
QIOChannel **dst)
{
@ -146,21 +148,34 @@ static void test_io_channel_setup_async(SocketAddress *listen_addr,
qio_channel_set_delay(*src, false);
test_io_channel_set_socket_bufs(*src, *dst);
object_unref(OBJECT(lioc));
*srv = QIO_CHANNEL(lioc);
g_main_loop_unref(data.loop);
}
static void test_io_channel_socket_path_exists(SocketAddress *addr,
bool expectExists)
{
if (addr->type != SOCKET_ADDRESS_TYPE_UNIX) {
return;
}
g_assert(g_file_test(addr->u.q_unix.path,
G_FILE_TEST_EXISTS) == expectExists);
}
static void test_io_channel(bool async,
SocketAddress *listen_addr,
SocketAddress *connect_addr,
bool passFD)
{
QIOChannel *src, *dst;
QIOChannel *src, *dst, *srv;
QIOChannelTest *test;
if (async) {
test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
test_io_channel_setup_async(listen_addr, connect_addr,
&srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@ -169,14 +184,25 @@ static void test_io_channel(bool async,
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
test_io_channel_socket_path_exists(listen_addr, true);
test = qio_channel_test_new();
qio_channel_test_run_threads(test, true, src, dst);
qio_channel_test_validate(test);
test_io_channel_socket_path_exists(listen_addr, true);
/* unref without close, to ensure finalize() cleans up */
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
test_io_channel_socket_path_exists(listen_addr, true);
test_io_channel_setup_async(listen_addr, connect_addr, &src, &dst);
object_unref(OBJECT(srv));
test_io_channel_socket_path_exists(listen_addr, false);
test_io_channel_setup_async(listen_addr, connect_addr,
&srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@ -189,10 +215,24 @@ static void test_io_channel(bool async,
qio_channel_test_run_threads(test, false, src, dst);
qio_channel_test_validate(test);
/* close before unref, to ensure finalize copes with already closed */
qio_channel_close(src, &error_abort);
qio_channel_close(dst, &error_abort);
test_io_channel_socket_path_exists(listen_addr, true);
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
test_io_channel_socket_path_exists(listen_addr, true);
qio_channel_close(srv, &error_abort);
test_io_channel_socket_path_exists(listen_addr, false);
object_unref(OBJECT(srv));
test_io_channel_socket_path_exists(listen_addr, false);
} else {
test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
test_io_channel_setup_sync(listen_addr, connect_addr,
&srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@ -201,14 +241,25 @@ static void test_io_channel(bool async,
g_assert(qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_SHUTDOWN));
g_assert(qio_channel_has_feature(dst, QIO_CHANNEL_FEATURE_SHUTDOWN));
test_io_channel_socket_path_exists(listen_addr, true);
test = qio_channel_test_new();
qio_channel_test_run_threads(test, true, src, dst);
qio_channel_test_validate(test);
test_io_channel_socket_path_exists(listen_addr, true);
/* unref without close, to ensure finalize() cleans up */
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
test_io_channel_socket_path_exists(listen_addr, true);
test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
object_unref(OBJECT(srv));
test_io_channel_socket_path_exists(listen_addr, false);
test_io_channel_setup_sync(listen_addr, connect_addr,
&srv, &src, &dst);
g_assert(!passFD ||
qio_channel_has_feature(src, QIO_CHANNEL_FEATURE_FD_PASS));
@ -221,8 +272,23 @@ static void test_io_channel(bool async,
qio_channel_test_run_threads(test, false, src, dst);
qio_channel_test_validate(test);
test_io_channel_socket_path_exists(listen_addr, true);
/* close before unref, to ensure finalize copes with already closed */
qio_channel_close(src, &error_abort);
qio_channel_close(dst, &error_abort);
test_io_channel_socket_path_exists(listen_addr, true);
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
test_io_channel_socket_path_exists(listen_addr, true);
qio_channel_close(srv, &error_abort);
test_io_channel_socket_path_exists(listen_addr, false);
object_unref(OBJECT(srv));
test_io_channel_socket_path_exists(listen_addr, false);
}
}
@ -316,7 +382,6 @@ static void test_io_channel_unix(bool async)
qapi_free_SocketAddress(listen_addr);
qapi_free_SocketAddress(connect_addr);
g_assert(g_file_test(TEST_SOCKET, G_FILE_TEST_EXISTS) == FALSE);
}
@ -335,7 +400,7 @@ static void test_io_channel_unix_fd_pass(void)
{
SocketAddress *listen_addr = g_new0(SocketAddress, 1);
SocketAddress *connect_addr = g_new0(SocketAddress, 1);
QIOChannel *src, *dst;
QIOChannel *src, *dst, *srv;
int testfd;
int fdsend[3];
int *fdrecv = NULL;
@ -359,7 +424,7 @@ static void test_io_channel_unix_fd_pass(void)
connect_addr->type = SOCKET_ADDRESS_TYPE_UNIX;
connect_addr->u.q_unix.path = g_strdup(TEST_SOCKET);
test_io_channel_setup_sync(listen_addr, connect_addr, &src, &dst);
test_io_channel_setup_sync(listen_addr, connect_addr, &srv, &src, &dst);
memcpy(bufsend, "Hello World", G_N_ELEMENTS(bufsend));
@ -412,6 +477,7 @@ static void test_io_channel_unix_fd_pass(void)
object_unref(OBJECT(src));
object_unref(OBJECT(dst));
object_unref(OBJECT(srv));
qapi_free_SocketAddress(listen_addr);
qapi_free_SocketAddress(connect_addr);
unlink(TEST_SOCKET);