From: Graham Leggett Date: Mon, 14 Sep 2009 21:00:19 +0000 (+0000) Subject: Backport from trunk: X-Git-Tag: 2.2.14~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5a5afe03b19fb53636198fb495676ceaeb115c3f;p=thirdparty%2Fapache%2Fhttpd.git Backport from trunk: htdbm: Fix possible buffer overflow if dbm database has very long values. PR: 30586 Submitted by: Dan Poirier git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@814852 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 3a4057c43d6..571ce25d424 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,9 @@ Changes with Apache 2.2.14 *) CVE-2009-3094: mod_proxy_ftp NULL pointer dereference on error paths. [Stefan Fritsch , Joe Orton] + *) htdbm: Fix possible buffer overflow if dbm database has very + long values. PR 30586 [Dan Poirier] + *) Add support for HTTP PUT to ab. [Jeff Barnes ] *) mod_ssl: Fix SSL_*_DN_UID variables to use the 'userID' attribute diff --git a/STATUS b/STATUS index 244c16acbf1..9b1ab9b6ebc 100644 --- a/STATUS +++ b/STATUS @@ -94,14 +94,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: +1: covener, poirier +1: minfrin (with r814779 for compiler warning fix) - * htdbm: Avoid buffer overflows. - PR: 30586 - Trunk patches: http://svn.apache.org/viewvc?view=rev&revision=797563 - http://svn.apache.org/viewvc?view=rev&revision=814781 - http://svn.apache.org/viewvc?view=rev&revision=814792 - 2.2.x patch: http://people.apache.org/~poirier/patch3-2.2.x-PR30586.txt - +1: poirier, minfrin, rpluem - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/support/htdbm.c b/support/htdbm.c index 24b4ff44834..5e4b8fb006d 100644 --- a/support/htdbm.c +++ b/support/htdbm.c @@ -219,7 +219,7 @@ static apr_status_t htdbm_del(htdbm_t *htdbm) static apr_status_t htdbm_verify(htdbm_t *htdbm) { apr_datum_t key, val; - char pwd[MAX_STRING_LEN] = {0}; + char *pwd; char *rec, *cmnt; key.dptr = htdbm->username; @@ -231,9 +231,9 @@ static apr_status_t htdbm_verify(htdbm_t *htdbm) rec = apr_pstrndup(htdbm->pool, val.dptr, val.dsize); cmnt = strchr(rec, ':'); if (cmnt) - strncpy(pwd, rec, cmnt - rec); + pwd = apr_pstrndup(htdbm->pool, rec, cmnt - rec); else - strcpy(pwd, rec); + pwd = apr_pstrdup(htdbm->pool, rec); return apr_password_validate(htdbm->userpass, pwd); } @@ -241,8 +241,7 @@ static apr_status_t htdbm_list(htdbm_t *htdbm) { apr_status_t rv; apr_datum_t key, val; - char *rec, *cmnt; - char kb[MAX_STRING_LEN]; + char *cmnt; int i = 0; rv = apr_dbm_firstkey(htdbm->dbm, &key); @@ -250,24 +249,19 @@ static apr_status_t htdbm_list(htdbm_t *htdbm) fprintf(stderr, "Empty database -- %s\n", htdbm->filename); return APR_ENOENT; } - rec = apr_pcalloc(htdbm->pool, HUGE_STRING_LEN); - fprintf(stderr, "Dumping records from database -- %s\n", htdbm->filename); - fprintf(stderr, " %-32sComment\n", "Username"); + fprintf(stderr, " %-32s Comment\n", "Username"); while (key.dptr != NULL) { rv = apr_dbm_fetch(htdbm->dbm, key, &val); if (rv != APR_SUCCESS) { fprintf(stderr, "Failed getting data from %s\n", htdbm->filename); return APR_EGENERAL; } - strncpy(kb, key.dptr, key.dsize); - kb[key.dsize] = '\0'; - fprintf(stderr, " %-32s", kb); - strncpy(rec, val.dptr, val.dsize); - rec[val.dsize] = '\0'; - cmnt = strchr(rec, ':'); + /* Note: we don't store \0-terminators on our dbm data */ + fprintf(stderr, " %-32.*s", (int)key.dsize, key.dptr); + cmnt = memchr(val.dptr, ':', val.dsize); if (cmnt) - fprintf(stderr, "%s", cmnt + 1); + fprintf(stderr, " %.*s", (int)(val.dptr+val.dsize - (cmnt+1)), cmnt + 1); fprintf(stderr, "\n"); rv = apr_dbm_nextkey(htdbm->dbm, &key); if (rv != APR_SUCCESS)