Commit e723cce8 authored by Jim Jagielski's avatar Jim Jagielski
Browse files

Merge r1808008, r1808085 from trunk:

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
parent 21964c05
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -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.

+0 −7
Original line number Diff line number Diff line
@@ -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
+17 −7
Original line number Diff line number Diff line
@@ -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;