File 0110-2164750-sfcb_handle_malformed_requests.patch of Package sblim-sfcb
--- ./httpAdapter.c.0110-2164750-sfcb_handle_malformed_requests.patch 2008-10-24 18:16:41.000000000 -0600
+++ ./httpAdapter.c 2008-10-24 18:19:32.000000000 -0600
@@ -75,6 +75,7 @@
static long keepaliveTimeout=15;
static long keepaliveMaxRequest=10;
static long numRequest;
+struct timeval httpSelectTimeout = {5, 0}; /* 5 sec. timeout for select() before read() */
#if defined USE_SSL
static SSL_CTX *ctx;
@@ -339,21 +340,36 @@
static int readData(CommHndl conn_fd, char *into, int length)
{
- int c = 0, r;
+ int c = 0, r, isReady;
+ fd_set httpfds;
+ FD_ZERO(&httpfds);
+ FD_SET(conn_fd.socket,&httpfds);
while (c < length) {
+ isReady = select(conn_fd.socket+1,&httpfds,NULL,NULL,&httpSelectTimeout);
+ if (isReady == 0) {
+ c = -1;
+ break;
+ }
r = commRead(conn_fd, into + c, length - c);
if (r < 0 && (errno == EINTR || errno == EAGAIN)) {
continue;
}
+ /* r==0 is a success condition for read(), but the loop should complete prior to this */
+ else if (r == 0) {
+ mlogf(M_INFO,M_SHOW,"--- commRead hit EOF sooner than expected\n");
+ c = -2;
+ break;
+ }
c += r;
}
return c;
}
-static void getPayload(CommHndl conn_fd, Buffer * b)
+static int getPayload(CommHndl conn_fd, Buffer * b)
{
int c = b->length - b->ptr;
+ int rc = 0;
b->content = (char *) malloc(b->content_length + 8);
if (c) memcpy(b->content, (b->data) + b->ptr, c);
@@ -362,8 +378,9 @@
c = b->content_length;
}
- readData(conn_fd, (b->content) + c, b->content_length - c);
+ rc = readData(conn_fd, (b->content) + c, b->content_length - c);
*((b->content) + b->content_length) = 0;
+ return rc;
}
void dumpResponse(RespSegments * rs)
@@ -582,30 +599,37 @@
#define hdrBufsize 5000
#define hdrLimmit 5000
-static int getHdrs(CommHndl conn_fd, Buffer * b, char *cmd)
+static int getHdrs(CommHndl conn_fd, Buffer * b, char *cmd)
{
int first=1,total=0,isReady;
- struct timeval httpTimeout;
fd_set httpfds;
int state=0;
FD_ZERO(&httpfds);
FD_SET(conn_fd.socket,&httpfds);
- httpTimeout.tv_sec=5;
- httpTimeout.tv_usec=0;
- isReady = select(conn_fd.socket+1,&httpfds,NULL,NULL,&httpTimeout);
- if (isReady == 0) return 3;
for (;;) {
+ isReady = select(conn_fd.socket+1,&httpfds,NULL,NULL,&httpSelectTimeout);
+ if (isReady == 0) return 3;
+
char buf[hdrBufsize];
int r = commRead(conn_fd, buf, sizeof(buf));
if (r < 0 && (errno == EINTR || errno == EAGAIN)) continue;
- if (r <= 0) break;
+ if (r == 0) {
+ if (b->size == 0) break;
+ if (strstr(b->data, "\r\n\r\n") == NULL &&
+ strstr(b->data, "\n\n") == NULL) {
+ mlogf(M_ERROR,M_SHOW,"-#- HTTP header ended prematurely\n");
+ state = 3;
+ break;
+ }
+ }
add2buffer(b, buf, r);
total+=r;
-// fprintf(stderr,"+++ buf: >%s<\n",buf);
+
+ /* on first run through, ensure that this is a POST req. */
if (r && first) {
if (strncasecmp(buf,cmd,strlen(cmd)) != 0) {
/* not what we expected - still continue to read to
@@ -614,7 +638,8 @@
}
first=0;
}
-
+
+ /* success condition: end of header */
if (strstr(b->data, "\r\n\r\n") != NULL ||
strstr(b->data, "\n\n") != NULL) {
break;
@@ -688,7 +713,7 @@
int badReq = 0;
rc=getHdrs(conn_fd, &inBuf,"POST ");
-
+
if (rc==1) {
genError(conn_fd, &inBuf, 501, "Not Implemented", NULL);
/* we continue to parse headers and empty the socket
@@ -851,7 +876,13 @@
len += hl =
sprintf(hdr, "<!-- xml -->\n<!-- auth: %s -->\n", inBuf.authorization);
- getPayload(conn_fd, &inBuf);
+ rc = getPayload(conn_fd, &inBuf);
+ if (rc < 0) {
+ genError(conn_fd, &inBuf, 400, "Bad Request", NULL);
+ _SFCB_TRACE(1, ("--- exiting after request timeout."));
+ commClose(conn_fd);
+ exit(1);
+ }
if (discardInput) {
free(hdr);
freeBuffer(&inBuf);
@@ -1293,12 +1324,10 @@
/* still in handshake */
FD_ZERO(&httpfds);
FD_SET(connFd,&httpfds);
- httpTimeout.tv_sec=5;
- httpTimeout.tv_usec=0;
if (sslerr == SSL_ERROR_WANT_WRITE) {
- isReady = select(connFd+1,NULL,&httpfds,NULL,&httpTimeout);
+ isReady = select(connFd+1,NULL,&httpfds,NULL,&httpSelectTimeout);
} else {
- isReady = select(connFd+1,&httpfds,NULL,NULL,&httpTimeout);
+ isReady = select(connFd+1,&httpfds,NULL,NULL,&httpSelectTimeout);
}
if (isReady == 0) {
intSSLerror("Timeout error accepting SSL connection");