1 --- a/src/server/frame/http.cpp Mon Jan 25 15:35:57 2010 +0530
2 +++ b/src/server/frame/http.cpp Mon Jan 25 18:05:23 2010 +0530
3 @@ -243,16 +243,47 @@
4 continue;
5 }
6
7 - t[pos] = toupper(p->param->name[0]);
8 - for(y = pos+1, z = 1; (t[y] = p->param->name[z]); y++, z++) {
9 - if(y >= (tsz - slack)) {
10 - tsz += REQ_MAX_LINE;
11 - t = (char *) REALLOC(t, tsz + 1);
12 + /*
13 + * If worst case p->param->name[1] is 0, REALLOC inside next for
14 + * loop will not be invoked so we need to make sure 3 more bytes at
15 + * pointer (t + pos) are available before next place condition
16 + * check + REALLOC is invoked. Note that Slack is incremented to 3
17 + * in the beginning.
18 + */
19 + if (pos >= (tsz - slack)) {
20 + tsz += REQ_MAX_LINE;
21 + t = (char *) REALLOC(t, tsz + 1);
22 + }
23 +
24 + if (p->param->name[0]) {
25 + t[pos] = toupper(p->param->name[0]);
26 + for(y = pos+1, z = 1; (t[y] = p->param->name[z]); y++, z++) {
27 + if(y >= (tsz - slack)) {
28 + tsz += REQ_MAX_LINE;
29 + t = (char *) REALLOC(t, tsz + 1);
30 + }
31 }
32 + } else {
33 + y = pos;
34 }
35
36 t[y++] = ':';
37 t[y++] = ' ';
38 +
39 + /*
40 + * Suppose REALLOC happened in previous for loop and loop exited
41 + * with y == (tsz - slack) And suppose p->param->value[0] is 0 then
42 + * we must check the available buffer in t here to make sure we
43 + * have at least 3 more bytes available to avoid overwriting the
44 + * allocated buffer. (Note that slack was incremented to 3 in
45 + * beginning). If p->param->value[0] is not 0 then REALLOC inside
46 + * next for loop will make sure that we have 3 bytes available
47 + * before next REALLOC is required.
48 + */
49 + if (y >= (tsz - slack)) {
50 + tsz += REQ_MAX_LINE;
51 + t = (char *) REALLOC(t, tsz + 1);
52 + }
53
54 for(z = 0; (t[y] = p->param->value[z]); ++y, ++z) {
55 if(y >= (tsz - slack)) {
1.1 --- a/src/server/safs/dbtsafs.h Mon Jan 25 15:35:57 2010 +0530
1.2 +++ b/src/server/safs/dbtsafs.h Mon Jan 25 18:05:23 2010 +0530
1.3 @@ -326,4 +326,5 @@
1.4 ResDef(DBT_nsfcsafEreport23, 395, "HTTP4395: Failed to set the max open descriptor in file cache")
1.5 ResDef(DBT_flexLogError4, 396, "HTTP4396: Log file %s should be removed before changing its format (ASCII <--> Binary)")
1.6 ResDef(DBT_flexLogError5, 397, "HTTP4397: Binary log file version mismatch error. Please remove the log file and restart the server" )
1.7 + ResDef(DBT_digestTooMany, 398, "HTTP4398: Too many parameters in Digest Authorization header (possibly an attack). Dropping excess parameters. Authentication in progress will fail")
1.8 END_STR(safs)
2.1 --- a/src/server/safs/digest.cpp Mon Jan 25 15:35:57 2010 +0530
2.2 +++ b/src/server/safs/digest.cpp Mon Jan 25 18:05:23 2010 +0530
2.3 @@ -69,6 +69,7 @@
2.4 #include "safs/dbtsafs.h"
2.5
2.6 #define AUTH_MAX_LINE 1024
2.7 +#define MAX_DIGEST_OPTIONS 16
2.8
2.9 /* local function declarations */
2.10 static char **sanitize(const char *);
2.11 @@ -140,10 +141,11 @@
2.12 char *work = NULL;
2.13 int i;
2.14
2.15 - /* 16 should be way more entries than we need */
2.16 - list = (char **) MALLOC(16*(sizeof(char *)));
2.17 - for (i=0; i < 16; i++)
2.18 + /* Only handle up to MAX_DIGEST_OPTIONS which is enough for valid uses */
2.19 + list = (char **) MALLOC(MAX_DIGEST_OPTIONS*(sizeof(char *)));
2.20 + for (i=0; i < MAX_DIGEST_OPTIONS; i++) {
2.21 list[i] = NULL;
2.22 + }
2.23
2.24 work = (char *) MALLOC(strlen(in) + 1);
2.25 strcpy(work, in);
2.26 @@ -165,6 +167,14 @@
2.27 *tmp = '\0';
2.28 list[i] = STRDUP(t); // XXX this is currently not free'd
2.29 i++;
2.30 +
2.31 + if (i == (MAX_DIGEST_OPTIONS - 1)) {
2.32 + // There should not be this many entries...
2.33 + // Stop processing them, something is wrong by now.
2.34 + ereport(LOG_SECURITY, XP_GetAdminStr(DBT_digestTooMany));
2.35 + goto bail;
2.36 + }
2.37 +
2.38 t = tmp;
2.39 }
2.40 }
2.41 @@ -173,7 +183,7 @@
2.42 /* catch the last entry */
2.43 *tmp = '\0';
2.44 list[i] = STRDUP(t); // XXX this is currently not free'd
2.45 -
2.46 + bail:
2.47 FREE(work);
2.48
2.49 return list;