From fde15ad27b1971f6fe3a847285d1e4a0465c2d5d Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Tue, 19 Sep 2017 10:14:01 +0000 Subject: [PATCH] Merge r1808008, r1808085 from trunk: MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 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 | 4 ++++ STATUS | 7 ------- support/htdigest.c | 24 +++++++++++++++++------- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/CHANGES b/CHANGES index 109b338b7c..e7a2d65763 100644 --- 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 ] + *) mod_proxy_wstunnel: Allow upgrade to any protocol dynamically. PR 61142. diff --git a/STATUS b/STATUS index bfcc4bb975..0ebc8f525b 100644 --- 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 diff --git a/support/htdigest.c b/support/htdigest.c index 018c0ea200..43f705442e 100644 --- a/support/htdigest.c +++ b/support/htdigest.c @@ -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; -- 2.40.0