httpd: fix CGI handling bug (we were closing wrong fd).

This commit is contained in:
Denis Vlasenko 2007-08-11 20:20:02 +00:00
parent f893da875a
commit e5d37ccb6e
2 changed files with 21 additions and 14 deletions

View File

@ -15,7 +15,7 @@ int vdprintf(int d, const char *format, va_list ap)
char buf[BUF_SIZE]; char buf[BUF_SIZE];
int len; int len;
len = vsprintf(buf, format, ap); len = vsnprintf(buf, BUF_SIZE, format, ap);
return write(d, buf, len); return write(d, buf, len);
} }
#endif #endif

View File

@ -989,8 +989,8 @@ static int sendCgi(const char *url,
const char *request, int bodyLen, const char *cookie, const char *request, int bodyLen, const char *cookie,
const char *content_type) const char *content_type)
{ {
int fromCgi[2]; /* pipe for reading data from CGI */ struct { int rd; int wr; } fromCgi; /* CGI -> httpd pipe */
int toCgi[2]; /* pipe for sending data to CGI */ struct { int rd; int wr; } toCgi; /* httpd -> CGI pipe */
char *fullpath; char *fullpath;
char *argp[] = { NULL, NULL }; char *argp[] = { NULL, NULL };
int pid = 0; int pid = 0;
@ -1000,9 +1000,9 @@ static int sendCgi(const char *url,
int status; int status;
size_t post_read_size, post_read_idx; size_t post_read_size, post_read_idx;
if (pipe(fromCgi) != 0) if (pipe(&fromCgi.rd) != 0)
return 0; return 0;
if (pipe(toCgi) != 0) if (pipe(&toCgi.rd) != 0)
return 0; return 0;
/* /*
@ -1039,13 +1039,13 @@ static int sendCgi(const char *url,
if (server_socket > 1) if (server_socket > 1)
close(server_socket); close(server_socket);
xmove_fd(toCgi[0], 0); /* replace stdin with the pipe */ xmove_fd(toCgi.rd, 0); /* replace stdin with the pipe */
xmove_fd(fromCgi[1], 1); /* replace stdout with the pipe */ xmove_fd(fromCgi.wr, 1); /* replace stdout with the pipe */
close(fromCgi[0]); close(fromCgi.rd);
close(fromCgi[1]); close(toCgi.wr);
/* Huh? User seeing stderr can be a security problem... /* Huh? User seeing stderr can be a security problem...
* and if CGI really wants that, it can always dup2(1,2)... * and if CGI really wants that, it can always dup2(1,2)...
* dup2(fromCgi[1], 2); */ * dup2(fromCgi.wr, 2); */
/* /*
* Find PATH_INFO. * Find PATH_INFO.
@ -1175,10 +1175,10 @@ static int sendCgi(const char *url,
buf_count = 0; buf_count = 0;
post_read_size = 0; post_read_size = 0;
post_read_idx = 0; /* for gcc */ post_read_idx = 0; /* for gcc */
inFd = fromCgi[0]; inFd = fromCgi.rd;
outFd = toCgi[1]; outFd = toCgi.wr;
close(fromCgi[1]); close(fromCgi.wr);
close(toCgi[0]); close(toCgi.rd);
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
while (1) { while (1) {
@ -1262,7 +1262,14 @@ static int sendCgi(const char *url,
/* Are we still buffering CGI output? */ /* Are we still buffering CGI output? */
if (buf_count >= 0) { if (buf_count >= 0) {
/* According to http://hoohoo.ncsa.uiuc.edu/cgi/out.html,
* CGI scripts MUST send their own header terminated by
* empty line, then data. That's why we have only one
* <cr><lf> pair here. We will output "200 OK" line
* if needed, but CGI still has to provide blank line
* between header and body */
static const char HTTP_200[] = "HTTP/1.0 200 OK\r\n"; static const char HTTP_200[] = "HTTP/1.0 200 OK\r\n";
/* Must use safe_read, not full_read, because /* Must use safe_read, not full_read, because
* CGI may output a few first bytes and then wait * CGI may output a few first bytes and then wait
* for POSTDATA without closing stdout. * for POSTDATA without closing stdout.