]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
htdigest: prevent buffer overflow when strings in lines are too long.
authorLuca Toscano <elukey@apache.org>
Mon, 11 Sep 2017 10:28:09 +0000 (10:28 +0000)
committerLuca Toscano <elukey@apache.org>
Mon, 11 Sep 2017 10:28:09 +0000 (10:28 +0000)
Reported by: Hanno Böck
PR: 61511

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1808008 13f79535-47bb-0310-9956-ffa450edef68

support/htdigest.c

index 018c0ea20023563dd17f8a04f36a28491535890a..43f705442ee70808776cce9e6ab1752c257f3d24 100644 (file)
@@ -59,6 +59,7 @@
 #endif /* APR_CHARSET_EBCDIC */
 
 #define MAX_STRING_LEN 256
+#define MAX_LINE_LEN 768
 
 apr_file_t *tfp = NULL;
 apr_file_t *errfile;
@@ -75,12 +76,16 @@ static void cleanup_tempfile_and_exit(int rc)
     exit(rc);
 }
 
-static void getword(char *word, char *line, char stop)
+static int getword(char *word, char *line, char stop)
 {
     int x = 0, y;
 
-    for (x = 0; ((line[x]) && (line[x] != stop)); x++)
+    for (x = 0; ((line[x]) && (line[x] != stop)); x++) {
+        if (x == (MAX_STRING_LEN - 1)) {
+            return 1;
+        }
         word[x] = line[x];
+    }
 
     word[x] = '\0';
     if (line[x])
@@ -88,6 +93,8 @@ static void getword(char *word, char *line, char stop)
     y = 0;
 
     while ((line[y++] = line[x++]));
+
+    return 0;
 }
 
 static int get_line(char *s, int n, apr_file_t *f)
@@ -127,7 +134,7 @@ static void add_password(const char *user, const char *realm, apr_file_t *f)
     char *pw;
     apr_md5_ctx_t context;
     unsigned char digest[16];
-    char string[3 * MAX_STRING_LEN]; /* this includes room for 2 * ':' + '\0' */
+    char string[MAX_LINE_LEN]; /* this includes room for 2 * ':' + '\0' */
     char pwin[MAX_STRING_LEN];
     char pwv[MAX_STRING_LEN];
     unsigned int i;
@@ -191,8 +198,8 @@ int main(int argc, const char * const argv[])
     char *dirname;
     char user[MAX_STRING_LEN];
     char realm[MAX_STRING_LEN];
-    char line[3 * MAX_STRING_LEN];
-    char l[3 * MAX_STRING_LEN];
+    char line[MAX_LINE_LEN];
+    char l[MAX_LINE_LEN];
     char w[MAX_STRING_LEN];
     char x[MAX_STRING_LEN];
     int found;
@@ -261,8 +268,11 @@ int main(int argc, const char * const argv[])
             continue;
         }
         strcpy(l, line);
-        getword(w, l, ':');
-        getword(x, l, ':');
+        if (getword(w, l, ':') || getword(x, l, ':')) {
+            apr_file_printf(errfile, "The following line contains a string longer than the "
+                                     "allowed maximum size (%i): %s\n", MAX_STRING_LEN - 1, line);
+            cleanup_tempfile_and_exit(1);
+        }
         if (strcmp(user, w) || strcmp(realm, x)) {
             putline(tfp, line);
             continue;