qemu-sockets: improve error reporting in unix_listen_opts

Coverity complains about not checking the returned value of mkstemp.  While
at it, also improve error checking for snprintf, and refine error messages
in general.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
This commit is contained in:
Paolo Bonzini 2015-01-26 12:12:24 +01:00 committed by Michael Tokarev
parent 52851b7e3d
commit b658c53d2b
1 changed files with 18 additions and 6 deletions

View File

@ -694,7 +694,7 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0); sock = qemu_socket(PF_UNIX, SOCK_STREAM, 0);
if (sock < 0) { if (sock < 0) {
error_setg_errno(errp, errno, "Failed to create socket"); error_setg_errno(errp, errno, "Failed to create Unix socket");
return -1; return -1;
} }
@ -703,9 +703,15 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
if (path && strlen(path)) { if (path && strlen(path)) {
snprintf(un.sun_path, sizeof(un.sun_path), "%s", path); snprintf(un.sun_path, sizeof(un.sun_path), "%s", path);
} else { } else {
char *tmpdir = getenv("TMPDIR"); const char *tmpdir = getenv("TMPDIR");
snprintf(un.sun_path, sizeof(un.sun_path), "%s/qemu-socket-XXXXXX", tmpdir = tmpdir ? tmpdir : "/tmp";
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;
}
/* /*
* This dummy fd usage silences the mktemp() unsecure warning. * This dummy fd usage silences the mktemp() unsecure warning.
* Using mkstemp() doesn't make things more secure here * Using mkstemp() doesn't make things more secure here
@ -713,13 +719,19 @@ int unix_listen_opts(QemuOpts *opts, Error **errp)
* to unlink first and thus re-open the race window. The * to unlink first and thus re-open the race window. The
* worst case possible is bind() failing, i.e. a DoS attack. * worst case possible is bind() failing, i.e. a DoS attack.
*/ */
fd = mkstemp(un.sun_path); close(fd); fd = mkstemp(un.sun_path);
if (fd < 0) {
error_setg_errno(errp, errno,
"Failed to make a temporary socket name in %s", tmpdir);
goto err;
}
close(fd);
qemu_opt_set(opts, "path", un.sun_path); qemu_opt_set(opts, "path", un.sun_path);
} }
unlink(un.sun_path); unlink(un.sun_path);
if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) { if (bind(sock, (struct sockaddr*) &un, sizeof(un)) < 0) {
error_setg_errno(errp, errno, "Failed to bind socket"); error_setg_errno(errp, errno, "Failed to bind socket to %s", un.sun_path);
goto err; goto err;
} }
if (listen(sock, 1) < 0) { if (listen(sock, 1) < 0) {