summaryrefslogtreecommitdiffstats
path: root/usr.sbin/slowcgi
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2013-10-29 17:59:47 +0000
committerflorian <florian@openbsd.org>2013-10-29 17:59:47 +0000
commitf4a8b9803bd14b3862dfb7cefd13b5b994811701 (patch)
tree7d6cad47505f2d16ff738c0969133fac6a813a7d /usr.sbin/slowcgi
parentadd missing heloname field for relayhost. (diff)
downloadwireguard-openbsd-f4a8b9803bd14b3862dfb7cefd13b5b994811701.tar.xz
wireguard-openbsd-f4a8b9803bd14b3862dfb7cefd13b5b994811701.zip
Fix a potential file descriptor overlap in exec_cgi() by making sure
that file descriptors zero to two are always open when starting slowcgi. pointed out, with and looks good to deraadt@
Diffstat (limited to 'usr.sbin/slowcgi')
-rw-r--r--usr.sbin/slowcgi/slowcgi.c28
1 files changed, 26 insertions, 2 deletions
diff --git a/usr.sbin/slowcgi/slowcgi.c b/usr.sbin/slowcgi/slowcgi.c
index 8a9eed84c54..539b6108ccf 100644
--- a/usr.sbin/slowcgi/slowcgi.c
+++ b/usr.sbin/slowcgi/slowcgi.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: slowcgi.c,v 1.24 2013/10/23 15:29:21 florian Exp $ */
+/* $OpenBSD: slowcgi.c,v 1.25 2013/10/29 17:59:47 florian Exp $ */
/*
* Copyright (c) 2013 David Gwynne <dlg@openbsd.org>
* Copyright (c) 2013 Florian Obser <florian@openbsd.org>
@@ -253,7 +253,25 @@ main(int argc, char *argv[])
{
extern char *__progname;
struct passwd *pw;
- int c;
+ struct stat sb;
+ int c, fd;
+
+ /*
+ * Ensure we have fds 0-2 open so that we have no fd overlaps
+ * in exec_cgi() later. Just exit on error, we don't have enough
+ * fds open to output an error message anywhere.
+ */
+ for (c=0; c < 3; c++) {
+ if (fstat(c, &sb) == -1) {
+ if ((fd = open("/dev/null", O_RDWR)) != -1) {
+ if (dup2(fd, c) == -1)
+ exit(1);
+ if (fd > c)
+ close(fd);
+ } else
+ exit(1);
+ }
+ }
while ((c = getopt(argc, argv, "ds:")) != -1) {
switch (c) {
@@ -851,12 +869,18 @@ exec_cgi(struct request *c)
close(s_in[0]);
close(s_out[0]);
close(s_err[0]);
+
if (dup2(s_in[1], STDIN_FILENO) == -1)
_exit(1);
if (dup2(s_out[1], STDOUT_FILENO) == -1)
_exit(1);
if (dup2(s_err[1], STDERR_FILENO) == -1)
_exit(1);
+
+ close(s_in[1]);
+ close(s_out[1]);
+ close(s_err[1]);
+
argv[0] = c->script_name;
argv[1] = NULL;
if ((env = calloc(c->env_count + 1, sizeof(char*))) == NULL)