Skip to content

Commit 4f278aa

Browse files
committed
Check return value of snprintf() and unlink()
No change in behavior if nothing goes wrong.
1 parent d9fca57 commit 4f278aa

File tree

4 files changed

+33
-16
lines changed

4 files changed

+33
-16
lines changed

agent/qrexec-agent.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -846,7 +846,9 @@ static void handle_trigger_io(void)
846846
if (command[command_len-1] != '\0')
847847
goto error;
848848

849-
snprintf(params.request_id.ident, sizeof(params.request_id), "SOCKET%d", client_fd);
849+
int res = snprintf(params.request_id.ident, sizeof(params.request_id), "SOCKET%d", client_fd);
850+
if (res < 0 || res >= (int)sizeof(params.request_id))
851+
abort();
850852
if (libvchan_send(ctrl_vchan, &hdr, sizeof(hdr)) != sizeof(hdr))
851853
handle_vchan_error("write hdr");
852854
if (libvchan_send(ctrl_vchan, &params, sizeof(params)) != sizeof(params))

agent/qrexec-client-vm.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -232,8 +232,7 @@ int main(int argc, char **argv)
232232
strncpy(params.target_domain, argv[optind],
233233
sizeof(params.target_domain) - 1);
234234

235-
snprintf(params.request_id.ident,
236-
sizeof(params.request_id.ident), "SOCKET");
235+
memcpy(params.request_id.ident, "SOCKET", sizeof("SOCKET"));
237236

238237
if (!write_all(trigger_fd, &hdr, sizeof(hdr))) {
239238
PERROR("write(hdr) to agent");

daemon/qrexec-client.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ static int handle_daemon_handshake(int fd)
171171

172172
static int connect_unix_socket(const char *domname)
173173
{
174-
int s, len;
174+
int s, len, res;
175175
struct sockaddr_un remote;
176176

177177
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
@@ -180,8 +180,13 @@ static int connect_unix_socket(const char *domname)
180180
}
181181

182182
remote.sun_family = AF_UNIX;
183-
snprintf(remote.sun_path, sizeof remote.sun_path,
184-
"%s/qrexec.%s", socket_dir, domname);
183+
res = snprintf(remote.sun_path, sizeof remote.sun_path,
184+
"%s/qrexec.%s", socket_dir, domname);
185+
if (res < 0)
186+
err(1, "snprintf");
187+
if (res >= (int)sizeof(remote.sun_path))
188+
errx(1, "%s/qrexec.%s is too long for AF_UNIX socket path",
189+
socket_dir, domname);
185190
len = strlen(remote.sun_path) + sizeof(remote.sun_family);
186191
if (connect(s, (struct sockaddr *) &remote, len) == -1) {
187192
PERROR("connect");

daemon/qrexec-daemon.c

+21-10
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,12 @@ static void unlink_qrexec_socket(void)
163163
"%s/qrexec.%s", socket_dir, remote_domain_name);
164164
if (v < (int)sizeof("/qrexec.") || v >= (int)sizeof(link_to_socket_name))
165165
abort();
166-
unlink(socket_address);
167-
unlink(link_to_socket_name);
166+
v = unlink(socket_address);
167+
if (v != 0 && !(v == -1 && errno == ENOENT))
168+
err(1, "unlink(%s)", socket_address);
169+
v = unlink(link_to_socket_name);
170+
if (v != 0 && !(v == -1 && errno == ENOENT))
171+
err(1, "unlink(%s)", link_to_socket_name);
168172
}
169173

170174
static void handle_vchan_error(const char *op)
@@ -178,12 +182,17 @@ static int create_qrexec_socket(int domid, const char *domname)
178182
{
179183
char socket_address[40];
180184
char link_to_socket_name[strlen(domname) + sizeof(socket_address)];
181-
182-
snprintf(socket_address, sizeof(socket_address),
183-
"%s/qrexec.%d", socket_dir, domid);
184-
snprintf(link_to_socket_name, sizeof link_to_socket_name,
185-
"%s/qrexec.%s", socket_dir, domname);
186-
unlink(link_to_socket_name);
185+
int res;
186+
187+
if ((unsigned)snprintf(socket_address, sizeof(socket_address),
188+
"%s/qrexec.%d", socket_dir, domid) >= sizeof(socket_address))
189+
errx(1, "socket name too long");
190+
if ((unsigned)snprintf(link_to_socket_name, sizeof link_to_socket_name,
191+
"%s/qrexec.%s", socket_dir, domname) >= sizeof link_to_socket_name)
192+
errx(1, "socket link name too long");
193+
res = unlink(link_to_socket_name);
194+
if (res != 0 && !(res == -1 && errno == ENOENT))
195+
err(1, "unlink(%s)", link_to_socket_name);
187196

188197
/* When running as root, make the socket accessible; perms on /var/run/qubes still apply */
189198
umask(0);
@@ -330,8 +339,10 @@ static void init(int xid)
330339
close(0);
331340

332341
if (!opt_direct) {
333-
snprintf(qrexec_error_log_name, sizeof(qrexec_error_log_name),
334-
"/var/log/qubes/qrexec.%s.log", remote_domain_name);
342+
if ((unsigned)snprintf(qrexec_error_log_name, sizeof(qrexec_error_log_name),
343+
"/var/log/qubes/qrexec.%s.log", remote_domain_name) >=
344+
sizeof(qrexec_error_log_name))
345+
errx(1, "remote domain name too long");
335346
umask(0007); // make the log readable by the "qubes" group
336347
logfd =
337348
open(qrexec_error_log_name, O_WRONLY | O_CREAT | O_TRUNC,

0 commit comments

Comments
 (0)