aboutsummaryrefslogtreecommitdiff
path: root/util/qemu-sockets.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2017-06-07 18:24:08 +0100
committerPeter Maydell <peter.maydell@linaro.org>2017-06-07 18:24:08 +0100
commitbbfa326fc8028e275eddf8c9965c2a1b59405b2e (patch)
tree18462ee41801d922e941ee50e1e4a54a96324464 /util/qemu-sockets.c
parent64175afc695c0672876fbbfc31b299c86d562cb4 (diff)
parentac06724a715864942e2b5e28f92d5d5421f0a0b0 (diff)
Merge remote-tracking branch 'remotes/bonzini/tags/for-upstream' into staging
* virtio-scsi use-after-free fix (Fam) * SMM fixes and improvements for TCG (myself, Mihail) * irqchip and AddressSpaceDispatch cleanups and fixes (Peter) * Coverity fix (Stefano) * NBD cleanups and fixes (Vladimir, Eric, myself) * RTC accuracy improvements and code cleanups (Guangrong+Yunfang) * socket error reporting improvement (Daniel) * GDB XML description for SSE registers (Abdallah) * kvmclock update fix (Denis) * SMM memory savings (Gonglei) * -cpu 486 fix (myself) * various bugfixes (Roman, Peter, myself, Thomas) * rtc-test improvement (Guangrong) * migration throttling fix (Felipe) * create docs/ subdirectories (myself) # gpg: Signature made Wed 07 Jun 2017 17:22:07 BST # gpg: using RSA key 0xBFFBD25F78C7AE83 # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * remotes/bonzini/tags/for-upstream: (31 commits) docs: create config/, devel/ and spin/ subdirectories cpus: reset throttle_thread_scheduled after sleep kvm: don't register smram_listener when smm is off nbd: make it thread-safe, fix qcow2 over nbd target/i386: Add GDB XML description for SSE registers i386/kvm: do not zero out segment flags if segment is unusable or not present edu: fix memory leak on msi_broken platforms linuxboot_dma: compile for i486 kvmclock: update system_time_msr address forcibly nbd: Fully initialize client in case of failed negotiation sockets: improve error reporting if UNIX socket path is too long i386: fix read/write cr with icount option target/i386: use multiple CPU AddressSpaces target/i386: enable A20 automatically in system management mode virtio-scsi: Unset hotplug handler when unrealize exec: simplify phys_page_find() params nbd/client.c: use errp instead of LOG nbd: add errp to read_sync, write_sync and drop_sync nbd: add errp parameter to nbd_wr_syncv() nbd: read_sync and friends: return 0 on success ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'util/qemu-sockets.c')
-rw-r--r--util/qemu-sockets.c68
1 files changed, 46 insertions, 22 deletions
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index b39ae74fe0..82290cb687 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -845,6 +845,8 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
{
struct sockaddr_un un;
int sock, fd;
+ char *pathbuf = NULL;
+ const char *path;
sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) {
@@ -852,20 +854,22 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
return -1;
}
- memset(&un, 0, sizeof(un));
- un.sun_family = AF_UNIX;
- if (saddr->path && strlen(saddr->path)) {
- snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path);
+ if (saddr->path && saddr->path[0]) {
+ path = saddr->path;
} else {
const char *tmpdir = getenv("TMPDIR");
tmpdir = tmpdir ? tmpdir : "/tmp";
- if (snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX",
- tmpdir) >= sizeof(un.sun_path)) {
- error_setg_errno(errp, errno,
- "TMPDIR environment variable (%s) too large", tmpdir);
- goto err;
- }
+ path = pathbuf = g_strdup_printf("%s/qemu-socket-XXXXXX", tmpdir);
+ }
+ if (strlen(path) > sizeof(un.sun_path)) {
+ error_setg(errp, "UNIX socket path '%s' is too long", path);
+ error_append_hint(errp, "Path must be less than %zu bytes\n",
+ sizeof(un.sun_path));
+ goto err;
+ }
+
+ if (pathbuf != NULL) {
/*
* This dummy fd usage silences the mktemp() unsecure warning.
* Using mkstemp() doesn't make things more secure here
@@ -873,24 +877,25 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
* to unlink first and thus re-open the race window. The
* worst case possible is bind() failing, i.e. a DoS attack.
*/
- fd = mkstemp(un.sun_path);
+ fd = mkstemp(pathbuf);
if (fd < 0) {
error_setg_errno(errp, errno,
- "Failed to make a temporary socket name in %s", tmpdir);
+ "Failed to make a temporary socket %s", pathbuf);
goto err;
}
close(fd);
- if (update_addr) {
- g_free(saddr->path);
- saddr->path = g_strdup(un.sun_path);
- }
}
- if (unlink(un.sun_path) < 0 && errno != ENOENT) {
+ if (unlink(path) < 0 && errno != ENOENT) {
error_setg_errno(errp, errno,
- "Failed to unlink socket %s", un.sun_path);
+ "Failed to unlink socket %s", path);
goto err;
}
+
+ memset(&un, 0, sizeof(un));
+ un.sun_family = AF_UNIX;
+ strncpy(un.sun_path, path, sizeof(un.sun_path));
+
if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path);
goto err;
@@ -900,9 +905,16 @@ static int unix_listen_saddr(UnixSocketAddress *saddr,
goto err;
}
+ if (update_addr && pathbuf) {
+ g_free(saddr->path);
+ saddr->path = pathbuf;
+ } else {
+ g_free(pathbuf);
+ }
return sock;
err:
+ g_free(pathbuf);
closesocket(sock);
return -1;
}
@@ -932,9 +944,16 @@ static int unix_connect_saddr(UnixSocketAddress *saddr,
qemu_set_nonblock(sock);
}
+ if (strlen(saddr->path) > sizeof(un.sun_path)) {
+ error_setg(errp, "UNIX socket path '%s' is too long", saddr->path);
+ error_append_hint(errp, "Path must be less than %zu bytes\n",
+ sizeof(un.sun_path));
+ goto err;
+ }
+
memset(&un, 0, sizeof(un));
un.sun_family = AF_UNIX;
- snprintf(un.sun_path, sizeof(un.sun_path), "%s", saddr->path);
+ strncpy(un.sun_path, saddr->path, sizeof(un.sun_path));
/* connect to peer */
do {
@@ -956,13 +975,18 @@ static int unix_connect_saddr(UnixSocketAddress *saddr,
}
if (rc < 0) {
- error_setg_errno(errp, -rc, "Failed to connect socket");
- close(sock);
- sock = -1;
+ error_setg_errno(errp, -rc, "Failed to connect socket %s",
+ saddr->path);
+ goto err;
}
g_free(connect_state);
return sock;
+
+ err:
+ close(sock);
+ g_free(connect_state);
+ return -1;
}
#else