]> granicus.if.org Git - apache/commitdiff
Merge r1808008, r1808085 from trunk:
authorJim Jagielski <jim@apache.org>
Tue, 19 Sep 2017 10:14:01 +0000 (10:14 +0000)
committerJim Jagielski <jim@apache.org>
Tue, 19 Sep 2017 10:14:01 +0000 (10:14 +0000)
htdigest: prevent buffer overflow when strings in lines are too long.

Reported by: Hanno Böck
PR: 61511

Update CHANGES after r1808008
Submitted by: elukey
Reviewed by: elukey, icing, ylavic

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1808853 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
STATUS
support/htdigest.c

diff --git a/CHANGES b/CHANGES
index 109b338b7c17d2639a5eae98f061fab00287e46a..e7a2d65763b2fe88d61956d2e4256b8fa174c78b 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,6 +6,10 @@ Changes with Apache 2.4.28
      main configuration file (httpd.conf) to register HTTP methods before the
      .htaccess files.  [Yann Ylavic]
 
+  *) htdigest: prevent a buffer overflow when a string exceeds the allowed max
+     length in a password file.
+     [Luca Toscano, Hanno Böck <hanno hboeck de>]
+
   *) mod_proxy_wstunnel: Allow upgrade to any protocol dynamically.
      PR 61142.
 
diff --git a/STATUS b/STATUS
index bfcc4bb975ae103de84b6f4a47a4a4934d66f33e..0ebc8f525beff5c355b559ff3b4ae6197cff1bd9 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -115,13 +115,6 @@ RELEASE SHOWSTOPPERS:
 PATCHES ACCEPTED TO BACKPORT FROM TRUNK:
   [ start all new proposals below, under PATCHES PROPOSED. ]
 
-  *) htdigest: prevent a buffer overflow when a string exceeds its maximum size
-               in a password file. PR: 61511
-     trunk patch: http://svn.apache.org/r1808008
-                  http://svn.apache.org/r1808085
-     2.4.x patch: svn merge -c1808008 -c1808085 ^/httpd/httpd/trunk .
-     +1: elukey, icing, ylavic
-
   *) Makefile: Use different variables to track normal modules and MPMs during
                build. Only the enabled MPM is uncommented in the configuration
                if multiple DSOs are built, and LoadModule for MPMs will now come
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;