Vulnerability Development mailing list archives

Re: thttpd 2.04 stack overflow


From: jef () ACME COM (Jef Poskanzer)
Date: Tue, 9 Nov 1999 17:58:45 -0800


Today I glanced at the thttpd 2.04 source code, wondering how seriously
thttpd parsed HTTP If-Modified-Since fields. I was horrified to see that
tdate_parse() scans %[a-zA-Z] into a fixed-size stack buffer.

You're right, that's pretty bad.  Thanks for the note.  Fortunately
the fix is trivial, and I had a new version of thttpd ready to go,
so I went ahead and released it.  The patch I applied is below, and
you can find the full tarchive at the usual place,
    http://www.acme.com/software/thttpd/
I was hoping to delay this release until I solve www.acme.com's current
bandwidth problems, but this is urgent enough to require an immediate fix.

By the way, this:

According to Netcraft, it's used
on 1.82% of all HTTP servers, behind only Apache, IIS, Enterprise, and
Rapidsite.

is somewhat of an overstatement.  There are actually only a hundred or
so sites running thttpd.  One of them is Demon Internet, a British
company which serves over 100,000 domains on a single SGI box running
their modified version of thttpd.

---
Jef

         Jef Poskanzer  jef () acme com  http://www.acme.com/jef/

*** tdate_parse.c       1999/09/15 16:09:36     1.1
--- tdate_parse.c       1999/11/10 01:16:39
***************
*** 211,217 ****
      */

      /* DD-mth-YY HH:MM:SS GMT */
!     if ( sscanf( cp, "%d-%[a-zA-Z]-%d %d:%d:%d GMT",
                &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
--- 211,217 ----
      */

      /* DD-mth-YY HH:MM:SS GMT */
!     if ( sscanf( cp, "%d-%400[a-zA-Z]-%d %d:%d:%d GMT",
                &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
***************
*** 225,231 ****
        }

      /* DD mth YY HH:MM:SS GMT */
!     else if ( sscanf( cp, "%d %[a-zA-Z] %d %d:%d:%d GMT",
                &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
--- 225,231 ----
        }

      /* DD mth YY HH:MM:SS GMT */
!     else if ( sscanf( cp, "%d %400[a-zA-Z] %d %d:%d:%d GMT",
                &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
***************
*** 239,245 ****
        }

      /* HH:MM:SS GMT DD-mth-YY */
!     else if ( sscanf( cp, "%d:%d:%d GMT %d-%[a-zA-Z]-%d",
                &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                &tm_year ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
--- 239,245 ----
        }

      /* HH:MM:SS GMT DD-mth-YY */
!     else if ( sscanf( cp, "%d:%d:%d GMT %d-%400[a-zA-Z]-%d",
                &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                &tm_year ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
***************
*** 253,259 ****
        }

      /* HH:MM:SS GMT DD mth YY */
!     else if ( sscanf( cp, "%d:%d:%d GMT %d %[a-zA-Z] %d",
                &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                &tm_year ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
--- 253,259 ----
        }

      /* HH:MM:SS GMT DD mth YY */
!     else if ( sscanf( cp, "%d:%d:%d GMT %d %400[a-zA-Z] %d",
                &tm_hour, &tm_min, &tm_sec, &tm_mday, str_mon,
                &tm_year ) == 6 &&
            scan_mon( str_mon, &tm_mon ) )
***************
*** 267,273 ****
        }

      /* wdy, DD-mth-YY HH:MM:SS GMT */
!     else if ( sscanf( cp, "%[a-zA-Z], %d-%[a-zA-Z]-%d %d:%d:%d GMT",
                str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
--- 267,273 ----
        }

      /* wdy, DD-mth-YY HH:MM:SS GMT */
!     else if ( sscanf( cp, "%400[a-zA-Z], %d-%400[a-zA-Z]-%d %d:%d:%d GMT",
                str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
***************
*** 283,289 ****
        }

      /* wdy, DD mth YY HH:MM:SS GMT */
!     else if ( sscanf( cp, "%[a-zA-Z], %d %[a-zA-Z] %d %d:%d:%d GMT",
                str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
--- 283,289 ----
        }

      /* wdy, DD mth YY HH:MM:SS GMT */
!     else if ( sscanf( cp, "%400[a-zA-Z], %d %400[a-zA-Z] %d %d:%d:%d GMT",
                str_wday, &tm_mday, str_mon, &tm_year, &tm_hour, &tm_min,
                &tm_sec ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
***************
*** 299,305 ****
        }

      /* wdy mth DD HH:MM:SS GMT YY */
!     else if ( sscanf( cp, "%[a-zA-Z] %[a-zA-Z] %d %d:%d:%d GMT %d",
                str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
                &tm_year ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&
--- 299,305 ----
        }

      /* wdy mth DD HH:MM:SS GMT YY */
!     else if ( sscanf( cp, "%400[a-zA-Z] %400[a-zA-Z] %d %d:%d:%d GMT %d",
                str_wday, str_mon, &tm_mday, &tm_hour, &tm_min, &tm_sec,
                &tm_year ) == 7 &&
            scan_wday( str_wday, &tm_wday ) &&



Current thread: