pkgsrc-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
pkg/60761: www/thttpd: three unfixed CVEs, one whose patch never worked, and a world-readable log
>Number: 60761
>Category: pkg
>Synopsis: www/thttpd: three unfixed CVEs, one whose patch never worked, and a world-readable log
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: pkg-manager
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Sep 22 03:10:00 +0000 2026
>Originator: Showta Ishizaki
>Release: pkgsrc CVS as of 2026-09-22
>Organization:
>Environment:
System: NetBSD 10.1 i386
Architecture: i386
Machine: i386
>Description:
www/thttpd is at 2.29, the last release ACME made. Three of the CVEs
filed against it are unfixed, and the patch for a fourth has never
worked.
CVE-2012-5640 -- crypt(3) returns NULL for a salt it does not
recognise, and auth_check2() hands the result straight to strcmp().
The salt comes from a user-written .htpasswd, so one malformed line
is enough to kill the server on the next request for that directory.
Which libc returns NULL varies: OpenBSD and illumos do, while NetBSD
and current Linux return "*0" instead. extras/htpasswd.c has the
same unchecked result, there passed to fprintf("%s").
CVE-2007-0158 -- five places index with length-1 without checking
the length. Three are in expand_symlinks(): a path of only slashes
under no_symlink_check reaches checked[-1]; an empty path reaches
rest[-1]; and a zero-length symlink target in the served tree
reaches lnk[-1]. The fourth is in auth_check2(), where fgets()
returns a line beginning with a NUL byte and line[-1] is read, which
is reachable the same way CVE-2012-5640 is. The fifth is in
thttpd.c: max_connects is fdwatch_get_nfiles() - SPARE_FDS with no
lower bound, so a descriptor limit of 10 leaves it at 0 and
connects[-1] is written.
CVE-2009-4491 -- the request line, the headers and the values
derived from them are written to the log and to syslog exactly as
the client sent them, so a request can place terminal escape
sequences in the log. This is not only make_log_entry(): eighteen
call sites write a client-controlled value, including the
"unparsable time" pair, check_referrer(), and the messages about a
path outside the web tree. No other packaging I looked at carries a
fix for this one, and it is not in ACME's 2.30 changelog either.
CVE-2005-3124 -- syslogtocern wrote to /tmp/stc1.$$, a name that can
be worked out in advance. pkgsrc patched that in 2005, in patch-ag,
replacing the name with mktemp(1). But the line the patch
substitutes carries a stray second backtick:
tmp1=``mktemp -t stc1.XXXXXX` || { echo ... }
so the script it produces does not parse. "sh -n" reports an
unmatched backtick, and running the installed one gives
syslogtocern: 34: Syntax error: "||" unexpected
before it does anything. The fix has therefore not been in effect
since it went in, and pkg-vulnerabilities has said "fixed in
2.25bnb4" for twenty years.
Three more things, none of them a CVE, kept in separate patches:
The access log is created world-readable. Both places that open it
use fopen(logfile, "a"), so a log that does not exist yet is created
0644 under the usual umask. Every line holds the request line, the
Referer, the User-Agent, and on an authenticated directory the
remote user name. It matters most after log rotation, where thttpd
recreates the file on SIGHUP.
extras/htpasswd.c reads lines into MAX_STRING_LEN (256) buffers.
A modern crypt(3) hash runs to about a hundred characters, so a line
written by another tool does not fit, and my_getline() truncates it
without saying so; the remainder is then read as the next line, so
adding a user to an existing file corrupts it. The same file leaves
pass uninitialised when fgets() fails, and reads pass[-1] for a line
that starts with a NUL byte.
The configure script's test programs declare main() without a return
type. C99 removed implicit int, so on a compiler that rejects it the
very first test fails with "C compiler cannot create executables".
gcc 14 and clang 16 and later are in that state; it is what stops the
build on Debian 13.
>How-To-Repeat:
For CVE-2012-5640, on a box whose crypt(3) returns NULL (OpenBSD,
illumos), put a line with a salt it does not know into a .htpasswd
and request the directory:
printf 'bob:$9$notasalt\n' > htdocs/priv/.htpasswd
thttpd -p 8080 -d htdocs -D -nos &
curl -u bob:pw http://127.0.0.1:8080/priv/
The server is gone afterwards. On a libc that returns "*0" the same
request survives, which is why the fix is worth having on all of
them rather than only where it crashes today.
For CVE-2009-4491, one request is enough:
curl -H "$(printf 'Referer: R\033]0;X\007')" http://127.0.0.1:8080/x
and the escape sequence is in the log file as sent.
For CVE-2007-0158, a zero-length symlink in the served tree, or a
.htpasswd line that begins with a NUL byte:
ln -s "" htdocs/empty && curl http://127.0.0.1:8080/empty
printf '\000bob:x\n' > htdocs/priv/.htpasswd
curl -u bob:x http://127.0.0.1:8080/priv/
Built with -fsanitize=address, the first reports an out-of-bounds
read in expand_symlinks() and the second one in auth_check2().
Linux cannot create the empty symlink, so there the second is the
one to use.
For CVE-2005-3124, no request is needed:
sh -n /usr/pkg/sbin/syslogtocern
syslogtocern: 34: Syntax error: "||" unexpected
>Fix:
The diff below is against CVS as of 2026-09-22 (www/thttpd/Makefile
rev 1.54, distinfo rev 1.21, PLIST rev 1.6, doc/pkg-vulnerabilities
rev 1.794). It applies with "patch -p0" from the top of the pkgsrc
tree. Because the patches are renamed, the old names need cvs rm
and the new files need cvs add; MESSAGE needs cvs rm too, since
patch cannot delete a file.
cvs rm www/thttpd/MESSAGE
cvs rm www/thttpd/patches/patch-a[abcdfg]
cvs add www/thttpd/files/README.pkgsrc
cvs add www/thttpd/patches/patch-CVE-2005-3124
cvs add www/thttpd/patches/patch-CVE-2007-0158
cvs add www/thttpd/patches/patch-CVE-2009-4491
cvs add www/thttpd/patches/patch-CVE-2012-5640
cvs add www/thttpd/patches/patch-Makefile.in
cvs add www/thttpd/patches/patch-cgi-src_Makefile.in
cvs add www/thttpd/patches/patch-configure
cvs add www/thttpd/patches/patch-extras_Makefile.in
cvs add www/thttpd/patches/patch-extras_htpasswd.c
cvs add www/thttpd/patches/patch-index.html
cvs add www/thttpd/patches/patch-libhttpd.c
cvs add www/thttpd/patches/patch-mmc.c
cvs add www/thttpd/patches/patch-thttpd.c
The four CVEs get one patch each, so that each can be read against
its advisory. That means four patches touch libhttpd.c, and they
are named so that they apply in the right order.
The six two-letter patches are renamed after the file they touch and
regenerated from a pristine 2.29, and all of them gain the
description pkglint asks for. patch-ag becomes patch-CVE-2005-3124,
since that is what it is for; its stray backtick is gone, and with
it gone the script parses and converts a syslog file into
CERN-format access_log and error_log as the manual page says.
patch-mmc.c is worth a word. It turns off mmap on NetBSD up to
1.5L, and the reason is in PR pkg/25487: before UBC arrived, mmap
and read were not kept in sync, so thttpd went on serving the old
contents of an edited page until it was restarted.
Three patches that are not CVEs:
patches/patch-thttpd.c the log is created 0640, not 0644
patches/patch-extras_htpasswd.c line length, and the fgets checks
patches/patch-configure C99 main()
patch-libhttpd.c is the one I would flag. It is not a security fix
and not an underflow -- the stock "i > 0" test already prevents the
index going negative. What it changes is that when PATH_INFO is the
whole of origfilename, the pathinfo part is now removed from it as
the comment there says it should be. FreeBSD ports and Debian both
carry it; Debian files it under "path-info" rather than as security.
The CVE patches do not depend on it.
doc/pkg-vulnerabilities gets four upper bounds moved to 2.29nb1.
Three of them are open-ended today, so audit-packages reports
thttpd whatever is installed:
thttpd-[0-9]* -> thttpd<2.29nb1 CVE-2009-4491
thttpd-[0-9]* -> thttpd<2.29nb1 CVE-2012-5640
thttpd-[0-9]* -> thttpd<2.29nb1 CVE-2007-0158
thttpd<2.25bnb4 -> thttpd<2.29nb1 CVE-2005-3124
The last one moves because the fix it refers to did not work. Its
URL also changes from the Secunia advisory, which no longer
resolves, to the CVE entry.
The Makefile gains LICENSE (28 files in the distfile carry the
two-clause notice and none carries the "Neither the name" clause),
two CFLAGS lines, and a rationale for MAKE_JOBS_SAFE:
cgi-src/Makefile.in builds strerror.o by running make in the parent
directory, and the top Makefile runs "all: this subdirs", so with -j
the parent's build and the subdirectory's can compile that object
into the same file at once. The CFLAGS lines are there because
glibc declares sigset(3) only under _XOPEN_SOURCE and illumos
declares crypt(3c) only under __EXTENSIONS__; configure links
against both and defines HAVE_SIGSET and HAVE_CRYPT, and gcc 14 then
refuses a call with no prototype in scope. Without them the package
does not build on Debian 13 or on OmniOS.
MESSAGE moves to files/README.pkgsrc, installed in share/doc/thttpd.
The guide says MESSAGE is for cases where lasting harm follows from
someone not reading it, and that configuration notes belong with the
package's documentation. The note is about making makeweb
set-group-id, which is the administrator's decision.
The rest of the Makefile is tidied to what pkglint wants: bsd.prefs.mk
before the "?=", DIST_SUBDIR and SITES.* in their places, and the
sed/mv in pre-configure moved into SUBST classes. The renaming of
htpasswd to thtpasswd stays a shell command, in post-patch, because
it has to happen after the patches (which still name
extras/htpasswd.c) and before the substitution.
Measured on eight machines, each with its own pkgsrc bootstrap:
NetBSD 10.1, FreeBSD 14.4, OpenBSD 7.9, DragonFly, OmniOS r151058,
Debian 13 on x86_64 and aarch64, and Alpine. Each run fetches
pkgsrc-current and builds and installs the package from source.
On each machine the unpatched 2.29 was built alongside and both were
driven with real requests. Where the 2002 configure stops the
unpatched build -- the Linux machines and OmniOS -- the control was
built with patch-configure alone, which writes the return type on
the test programs' main() and touches none of thttpd's own code.
CVE-2012-5640 stock dies, patched answers 401
all eight
CVE-2009-4491 stock writes the raw ESC, patched writes \x1b
all eight
CVE-2005-3124 the installed syslogtocern parses and converts a
syslog file; putting the second backtick back makes
it stop parsing again
all eight
CVE-2007-0158 stock reports the out-of-bounds read under ASan,
patched is clean
NetBSD and FreeBSD by both routes, the three Linux
machines by the .htpasswd one
The underflow is driven two ways because no single one reaches every
machine: a zero-length symlink in the served tree, which Linux
cannot create, and a .htpasswd line beginning with a NUL byte, which
any of them can. The first lands in expand_symlinks() and the
second in auth_check2(), so between them the two guarded sites in
libhttpd.c are both exercised. On NetBSD the sanitizer will not
start while ASLR is on; paxctl +a on the test binary is enough.
The pkg-vulnerabilities change was checked by taking the published
file, applying the same four edits, and running pkg_admin audit-pkg
against thttpd-2.29nb1: three entries before, none after, on all
eight.
Not run: the underflow on OpenBSD, DragonFly and OmniOS. There is
no sanitizer to observe the read with, and I could not put one
there:
OpenBSD cc: error: unsupported option '-fsanitize=address'
for target 'amd64-unknown-openbsd7.9'
DragonFly cannot find -lasan -- the base compiler takes the
option but has no runtime, and the dports gcc14 has
none either
OmniOS gcc: error: -fsanitize=address is not supported in
this configuration -- both gcc13 and gcc14 are built
with libsanitizer off
The patched package is built, installed and run on all three, and
the other three CVEs are exercised there. The two guarded sites
are reached on five machines across three operating systems and two
architectures, so no line of the patch is unexercised.
The distfile matches distinfo, and all thirteen patches apply to it
in order with no fuzz.
pkglint 23.21.1 goes from 8 errors and 4 warnings to none.
Index: www/thttpd/Makefile
===================================================================
RCS file: /cvsroot/pkgsrc/www/thttpd/Makefile,v
retrieving revision 1.54
diff -u -r1.54 Makefile
--- www/thttpd/Makefile
+++ www/thttpd/Makefile
@@ -1,63 +1,96 @@
# $NetBSD: Makefile,v 1.54 2025/03/30 10:02:53 nia Exp $
-DISTNAME= thttpd-2.29
-CATEGORIES= www
-MASTER_SITES= https://www.acme.com/software/thttpd/
-DISTFILES= ${DISTNAME}${EXTRACT_SUFX} \
- ${NETBSD_LOGO}
-DIST_SUBDIR= ${PKGNAME_NOREV}
+DISTNAME= thttpd-2.29
+PKGREVISION= 1
+CATEGORIES= www
+MASTER_SITES= https://www.acme.com/software/thttpd/
+DIST_SUBDIR= ${PKGNAME_NOREV}
+DISTFILES= ${DISTNAME}${EXTRACT_SUFX} ${NETBSD_LOGO}
+EXTRACT_ONLY= ${DISTNAME}${EXTRACT_SUFX}
+NETBSD_LOGO= sitedrivenby.gif
+SITES.${NETBSD_LOGO}= http://www.NetBSD.org/images/logos/
MAINTAINER= pkgsrc-users%NetBSD.org@localhost
HOMEPAGE= https://www.acme.com/software/thttpd/
COMMENT= Tiny/turbo/throttling HTTP server
+LICENSE= 2-clause-bsd
-EXTRACT_ONLY= ${DISTNAME}${EXTRACT_SUFX}
+GNU_CONFIGURE= yes
-NETBSD_LOGO= sitedrivenby.gif
-SITES.${NETBSD_LOGO}= http://www.NetBSD.org/images/logos/
+# cgi-src/Makefile.in builds strerror.o by running make in the parent
+# directory ("cd .. ; $(MAKE) strerror.o"), and the top Makefile runs
+# "all: this subdirs", so with -j the parent's own build and the
+# subdirectory's can compile that object into the same file at once.
+MAKE_JOBS_SAFE= no
-GNU_CONFIGURE= yes
+.include "../../mk/bsd.prefs.mk"
# Note: this pkg auto-detects IPv6.
-BUILD_DEFS+= IPV6_READY
-# thttpd syslogs at level LOG_DAEMON by default
-# change this to your preferred syslog level
+BUILD_DEFS+= IPV6_READY
+
+# thttpd syslogs at level LOG_DAEMON by default; change this to your
+# preferred syslog level.
THTTPD_LOG_FACILITY?= LOG_DAEMON
BUILD_DEFS+= THTTPD_LOG_FACILITY
+# glibc declares sigset(3) only under _XOPEN_SOURCE. configure finds the
+# symbol anyway (it links), so HAVE_SIGSET is defined and thttpd.c calls it
+# with no prototype in scope -- an error with gcc 14 and later, where C23
+# made implicit declarations fatal.
+CFLAGS.Linux+= -D_GNU_SOURCE
+
+# illumos declares crypt(3c) in <unistd.h> only under __EXTENSIONS__, and
+# thttpd includes no <crypt.h>. Same failure mode as the Linux case above:
+# configure links against libc and sets HAVE_CRYPT, then gcc 14 refuses the
+# implicit declaration.
+CFLAGS.SunOS+= -D__EXTENSIONS__
+
+CFLAGS.SCO_SV+= -DMAXPATHLEN=255 -DS_IFSOCK=0
+
EGDIR= ${PREFIX}/share/examples
+DOCDIR= ${PREFIX}/share/doc/thttpd
+
CONF_FILES= ${EGDIR}/thttpd.conf ${PKG_SYSCONFDIR}/thttpd.conf
RCD_SCRIPTS= thttpd
-INSTALLATION_DIRS= ${PKGMANDIR}/man1 share/thttpd ${EGDIR}
+INSTALLATION_DIRS= ${PKGMANDIR}/man1 share/thttpd ${EGDIR} ${DOCDIR}
SUBST_CLASSES+= paths
-SUBST_FILES.paths= thttpd.conf
-SUBST_VARS.paths= PREFIX
SUBST_STAGE.paths= pre-configure
+SUBST_FILES.paths= thttpd.conf README.pkgsrc
+SUBST_VARS.paths= PREFIX
-MAKE_JOBS_SAFE= no
+# htpasswd(1) is a common name, so the package installs it as thtpasswd.
+# post-patch does the renaming: after the patches, which still name
+# extras/htpasswd.c, and before this substitution runs.
+SUBST_CLASSES+= thtpasswd
+SUBST_STAGE.thtpasswd= pre-configure
+SUBST_MESSAGE.thtpasswd= Renaming htpasswd to thtpasswd.
+SUBST_FILES.thtpasswd= thttpd.8 extras/Makefile.in extras/thtpasswd.c
+SUBST_SED.thtpasswd= -e 's,\.htpasswd,@DOTHTPASSWD@,g'
+SUBST_SED.thtpasswd+= -e 's,htpasswd,thtpasswd,g'
+SUBST_SED.thtpasswd+= -e 's,@DOTHTPASSWD@,.htpasswd,g'
-CFLAGS.SCO_SV+= -DMAXPATHLEN=255 -DS_IFSOCK=0
+SUBST_CLASSES+= logfac
+SUBST_STAGE.logfac= pre-configure
+SUBST_MESSAGE.logfac= Setting the syslog facility.
+SUBST_FILES.logfac= config.h
+SUBST_SED.logfac= -e 's,LOG_DAEMON,${THTTPD_LOG_FACILITY},'
post-extract:
${CP} ${FILESDIR}/thttpd.conf ${WRKSRC}
+ ${CP} ${FILESDIR}/README.pkgsrc ${WRKSRC}
-pre-configure:
+post-patch:
${MV} ${WRKSRC}/extras/htpasswd.1 ${WRKSRC}/extras/thtpasswd.1
${MV} ${WRKSRC}/extras/htpasswd.c ${WRKSRC}/extras/thtpasswd.c
- for FILE in thttpd.8 extras/Makefile.in extras/thtpasswd.c; do \
- ${MV} -f ${WRKSRC}/$${FILE} ${WRKSRC}/$${FILE}.bak; \
- ${SED} -e "s,\.htpasswd,XXX,g;s,htpasswd,thtpasswd,g;s,XXX,.htpasswd,g" \
- ${WRKSRC}/$${FILE}.bak > ${WRKSRC}/$${FILE}; \
- done
- ${MV} -f ${WRKSRC}/config.h ${WRKSRC}/config.h.bak
- ${SED} -e "s/LOG_DAEMON/${THTTPD_LOG_FACILITY}/" ${WRKSRC}/config.h.bak \
- > ${WRKSRC}/config.h
post-install:
- ${INSTALL_DATA} ${WRKSRC}/thttpd.conf ${DESTDIR}${PREFIX}/share/examples
- ${INSTALL_DATA} ${WRKSRC}/index.html ${DESTDIR}${PREFIX}/share/thttpd
- ${INSTALL_DATA} ${DISTDIR}/${DIST_SUBDIR}/sitedrivenby.gif ${DESTDIR}${PREFIX}/share/thttpd
+ ${INSTALL_DATA} ${WRKSRC}/README.pkgsrc ${DESTDIR}${DOCDIR}
+ ${INSTALL_DATA} ${WRKSRC}/thttpd.conf ${DESTDIR}${EGDIR}
+ ${INSTALL_DATA} ${WRKSRC}/index.html \
+ ${DESTDIR}${PREFIX}/share/thttpd
+ ${INSTALL_DATA} ${DISTDIR}/${DIST_SUBDIR}/${NETBSD_LOGO} \
+ ${DESTDIR}${PREFIX}/share/thttpd
.include "../../mk/bsd.pkg.mk"
Index: www/thttpd/distinfo
===================================================================
RCS file: /cvsroot/pkgsrc/www/thttpd/distinfo,v
retrieving revision 1.21
diff -u -r1.21 distinfo
--- www/thttpd/distinfo
+++ www/thttpd/distinfo
@@ -6,9 +6,16 @@
BLAKE2s (thttpd-2.29/thttpd-2.29.tar.gz) = 023ee26357ec155995627c937e282ce5077dd1413f1f69f2f5927c883b2dca98
SHA512 (thttpd-2.29/thttpd-2.29.tar.gz) = e02ed5b889eb3c875d56503093777c542316165a8df2d83e539337fb0759b6d9728fd484123dd903af57b06c97fe339055b816cca64778b7369b94020bd61ab6
Size (thttpd-2.29/thttpd-2.29.tar.gz) = 133967 bytes
-SHA1 (patch-aa) = 0f739bebf1ade45a9b9819fc92d48eeb1004eb66
-SHA1 (patch-ab) = c6d6a20a00b4ceaf409b849982b8e963debf9530
-SHA1 (patch-ac) = f7fe1fed88b4cb33c9456d6fdc13e2bbc175ced6
-SHA1 (patch-ad) = 234127aaf4a3b5e6536bd08cc80f823800240fac
-SHA1 (patch-af) = 5160b635cdf9b3c997e93e039ef2764f77857018
-SHA1 (patch-ag) = 01410f8d293e2d4033f2a1119b21c05e21dfefbe
+SHA1 (patch-CVE-2005-3124) = af34d681b00af143ea86b696ae52b8b19fb619f7
+SHA1 (patch-CVE-2007-0158) = 49428634a39e4bda2f1d0a0a15cc62450c1259d1
+SHA1 (patch-CVE-2009-4491) = 37fa7858d14c7afff9d22ed1aa423b10cfe80516
+SHA1 (patch-CVE-2012-5640) = dda5e5a3e3b40e9d2997952f729e44d2d0ef58d1
+SHA1 (patch-Makefile.in) = 4c5b92df9e28d14ff83d00a4d951efa4595532ac
+SHA1 (patch-cgi-src_Makefile.in) = b80257756fcbb769b6540440b476f7548a5f117d
+SHA1 (patch-configure) = c3a09ec45abbfed2dced7e861333cf4376af2fbb
+SHA1 (patch-extras_Makefile.in) = c0c0df11f5ca945ef588d47a17906ad2d1c6c86c
+SHA1 (patch-extras_htpasswd.c) = 5cd23587d0a6d483462866c96fce5f2d31754556
+SHA1 (patch-index.html) = 2a7b22d91f8ef8cad7eecabdd8cb76fb44076b3e
+SHA1 (patch-libhttpd.c) = 89660ecceb2c4e3242c38a78f734db854d028f31
+SHA1 (patch-mmc.c) = 4052750ad1318f1d6776087f743a15ff609aed8c
+SHA1 (patch-thttpd.c) = 77e8de4f058ef27dc9463614e0c14295f0460fcb
Index: www/thttpd/PLIST
===================================================================
RCS file: /cvsroot/pkgsrc/www/thttpd/PLIST,v
retrieving revision 1.6
diff -u -r1.6 PLIST
--- www/thttpd/PLIST
+++ www/thttpd/PLIST
@@ -12,6 +12,7 @@
sbin/syslogtocern
sbin/thtpasswd
sbin/thttpd
+share/doc/thttpd/README.pkgsrc
share/examples/thttpd.conf
share/thttpd/index.html
share/thttpd/sitedrivenby.gif
Index: www/thttpd/patches/patch-CVE-2005-3124
===================================================================
RCS file: www/thttpd/patches/patch-CVE-2005-3124
diff -N www/thttpd/patches/patch-CVE-2005-3124
--- /dev/null
+++ www/thttpd/patches/patch-CVE-2005-3124
@@ -0,0 +1,34 @@
+$NetBSD$
+
+CVE-2005-3124 -- the script wrote to /tmp/stc1.$$, a name that can be
+worked out in advance, so anyone with write access to /tmp could put a
+symlink there and have the script write through it. Use mktemp(1) and
+remove the file on the way out. NVD says this was fixed before 2.23,
+but 2.29 still has the /tmp name, which is why the patch is still here.
+
+The line as written carried a stray second backtick, so the script it
+produced did not parse -- "sh -n" reports an unmatched backtick, and
+running it gives
+
+ syslogtocern: 34: Syntax error: "||" unexpected
+
+before it does anything. That has been so since the patch was added in
+2005, so the installed syslogtocern has never run. Nobody was exposed
+to the symlink attack by it, because a script that does not parse does
+not write anywhere; the tool was simply dead. With the backtick removed
+it parses, keeps the mktemp(1) protection, and converts a syslog file
+into CERN-format access_log and error_log as the manual page says.
+
+--- extras/syslogtocern.orig 2005-05-20 19:10:25.000000000 +0000
++++ extras/syslogtocern
+@@ -31,8 +31,8 @@
+ exit 1
+ fi
+
+-tmp1=/tmp/stc1.$$
+-rm -f $tmp1
++tmp1=`mktemp -t stc1.XXXXXX` || { echo "$0: Cannot create temporary file" >&2; exit 1; }
++trap " [ -f \"$tmp1\" ] && /bin/rm -f -- \"$tmp1\"" 0 1 2 3 13 15
+
+ # Gather up all the thttpd entries.
+ egrep -h ' thttpd\[' "$@" > $tmp1
Index: www/thttpd/patches/patch-CVE-2007-0158
===================================================================
RCS file: www/thttpd/patches/patch-CVE-2007-0158
diff -N www/thttpd/patches/patch-CVE-2007-0158
--- /dev/null
+++ www/thttpd/patches/patch-CVE-2007-0158
@@ -0,0 +1,112 @@
+$NetBSD$
+
+CVE-2007-0158 -- buffer underflow. Five places index with length-1
+without checking the length. Three are in expand_symlinks():
+
+ - with no_symlink_check (chroot mode) and a path of only slashes, the
+ trailing-slash trim drives checkedlen to 0 and then reads
+ checked[-1]; stat("/") always succeeds, so "/" reaches it;
+ - with an empty path, rest[restlen-1] reads before the buffer;
+ - with a zero-length symlink target in the served tree, readlink()
+ returns 0 and lnk[linklen-1] reads before the stack buffer.
+
+The fourth is in auth_check2(): fgets() returns non-NULL for a line that
+begins with a NUL byte, strlen() is then 0, and line[l-1] reads before
+the 500-byte stack buffer. The .htpasswd is user-written, so this is
+reached the same way CVE-2012-5640 is, by requesting a protected
+directory.
+
+The fifth is in thttpd.c: max_connects is fdwatch_get_nfiles() minus
+SPARE_FDS, with no lower bound, so a file descriptor limit of 10 leaves
+it at 0. connects[max_connects-1].next_free_connect is then written
+before the array; malloc(0) returns a pointer, so the allocation does
+not fail first. With that limit thttpd starts and then refuses every
+connection (measured: HTTP 200 normally, no answer at all under
+"ulimit -n 10"), which is what max_connects <= 0 looks like from
+outside. It now exits with a message instead.
+
+The four in libhttpd.c fire under AddressSanitizer on the routines
+extracted unchanged from 2.29, and are clean once guarded.
+
+What other packaging carries, for comparison:
+
+ site checkedlen restlen readlink auth_check2
+ FreeBSD ports yes yes no no
+ Debian (2.25b-11) no yes* no no
+ ACME 2.30 (unreleased) - - yes -
+
+ * Debian drops the trailing-slash trim entirely rather than guarding it.
+
+(FreeBSD and Debian also change the PATH_INFO trimming near
+origfilename[i-1]. That one is not a length-1 underflow -- the stock
+"i > 0" test already prevents it -- it is a behaviour change, and it is
+kept separate in patch-libhttpd.c.)
+
+ACME's 2.30 changelog lists "off-by-one illegal memory access in
+expand_symlinks()", which is the readlink() case.
+
+--- libhttpd.c.orig
++++ libhttpd.c
+@@ -1117,9 +1117,11 @@
+ /* Read it. */
+ while ( fgets( line, sizeof(line), fp ) != (char*) 0 )
+ {
+- /* Nuke newline. */
++ /* Nuke newline. A NUL byte in the file leaves strlen() at 0, and
++ ** line[l-1] would then read before the buffer.
++ */
+ l = strlen( line );
+- if ( line[l - 1] == '\n' )
++ if ( l > 0 && line[l - 1] == '\n' )
+ line[l - 1] = '\0';
+ /* Split into user and encrypted password. */
+ cryp = strchr( line, ':' );
+@@ -1486,7 +1488,7 @@
+ httpd_realloc_str( &checked, &maxchecked, checkedlen );
+ (void) strcpy( checked, path );
+ /* Trim trailing slashes. */
+- while ( checked[checkedlen - 1] == '/' )
++ while ( checkedlen > 0 && checked[checkedlen - 1] == '/' )
+ {
+ checked[checkedlen - 1] = '\0';
+ --checkedlen;
+@@ -1505,7 +1507,7 @@
+ restlen = strlen( path );
+ httpd_realloc_str( &rest, &maxrest, restlen );
+ (void) strcpy( rest, path );
+- if ( rest[restlen - 1] == '/' )
++ if ( restlen > 0 && rest[restlen - 1] == '/' )
+ rest[--restlen] = '\0'; /* trim trailing slash */
+ if ( ! tildemapped )
+ /* Remove any leading slashes. */
+@@ -1623,7 +1625,9 @@
+ return (char*) 0;
+ }
+ lnk[linklen] = '\0';
+- if ( lnk[linklen - 1] == '/' )
++ /* An empty symlink target makes readlink() return 0, and
++ ** lnk[linklen-1] then reads lnk[-1], underflowing the buffer. */
++ if ( linklen > 0 && lnk[linklen - 1] == '/' )
+ lnk[--linklen] = '\0'; /* trim trailing slash */
+
+ /* Insert the link contents in front of the rest of the filename. */
+--- thttpd.c.orig
++++ thttpd.c
+@@ -554,6 +554,17 @@
+ exit( 1 );
+ }
+ max_connects -= SPARE_FDS;
++ if ( max_connects <= 0 )
++ {
++ /* With a file descriptor limit this low there is no room for even one
++ ** connection, and connects[max_connects-1] below would write before
++ ** the array. malloc(0) returns a pointer, so this is not caught by
++ ** the allocation failing.
++ */
++ syslog( LOG_CRIT, "file descriptor limit is too low for any connection" );
++ (void) fprintf( stderr, "%s: file descriptor limit is too low for any connection\n", argv0 );
++ exit( 1 );
++ }
+
+ /* Chroot if requested. */
+ if ( do_chroot )
Index: www/thttpd/patches/patch-CVE-2009-4491
===================================================================
RCS file: www/thttpd/patches/patch-CVE-2009-4491
diff -N www/thttpd/patches/patch-CVE-2009-4491
--- /dev/null
+++ www/thttpd/patches/patch-CVE-2009-4491
@@ -0,0 +1,332 @@
+$NetBSD$
+
+CVE-2009-4491 -- log injection. thttpd writes the request line, the
+headers and values derived from them to the log exactly as the client
+sent them, so a request can place terminal escape sequences into the
+log. Control characters are written as \xHH instead.
+
+This is not only the access log. Every one of these logs a value the
+client controls, and none of them sanitised it:
+
+ make_log_entry() the access log and its syslog form: URL, Referer,
+ User-Agent, remote user
+ the "unparsable time" pair the raw If-Modified-Since and If-Range
+ header values
+ check_referrer() the Referer host, the URL and the Referer
+ thirteen more the URL or the expanded filename, in the "goes
+ outside the web tree", "tried to index a
+ directory", "tried to retrieve an auth file",
+ "isn't CGI", opendir, execve and spawn messages
+ thttpd.c the URL in the write-error message
+
+httpd_log_escape() is exported because thttpd.c needs it too. It hands
+back a pointer into a small ring of static buffers so that several
+values can be escaped in one syslog() call; thttpd is single-threaded,
+so that is safe.
+
+Not in ACME's 2.30 changelog, and not carried by FreeBSD ports, Debian,
+Fedora, Alpine, MacPorts or Void.
+
+--- libhttpd.c.orig
++++ libhttpd.c
+@@ -172,6 +172,7 @@
+ static int cgi( httpd_conn* hc );
+ static int really_start_request( httpd_conn* hc, struct timeval* nowP );
+ static void make_log_entry( httpd_conn* hc, struct timeval* nowP );
++static char* log_escape( char* dst, size_t dstsize, const char* src );
+ static int check_referrer( httpd_conn* hc );
+ static int really_check_referrer( httpd_conn* hc );
+ static int sockaddr_check( httpd_sockaddr* saP );
+@@ -1619,7 +1620,7 @@
+ ++nlinks;
+ if ( nlinks > MAX_LINKS )
+ {
+- syslog( LOG_ERR, "too many symlinks in %.80s", path );
++ syslog( LOG_ERR, "too many symlinks in %.80s", httpd_log_escape( path ) );
+ return (char*) 0;
+ }
+ lnk[linklen] = '\0';
+@@ -2173,7 +2174,8 @@
+ cp = &buf[18];
+ hc->if_modified_since = tdate_parse( cp );
+ if ( hc->if_modified_since == (time_t) -1 )
+- syslog( LOG_DEBUG, "unparsable time: %.80s", cp );
++ syslog( LOG_DEBUG, "unparsable time: %.80s",
++ httpd_log_escape( cp ) );
+ }
+ else if ( strncasecmp( buf, "Cookie:", 7 ) == 0 )
+ {
+@@ -2214,7 +2216,8 @@
+ cp = &buf[9];
+ hc->range_if = tdate_parse( cp );
+ if ( hc->range_if == (time_t) -1 )
+- syslog( LOG_DEBUG, "unparsable time: %.80s", cp );
++ syslog( LOG_DEBUG, "unparsable time: %.80s",
++ httpd_log_escape( cp ) );
+ }
+ else if ( strncasecmp( buf, "Content-Type:", 13 ) == 0 )
+ {
+@@ -2380,7 +2383,7 @@
+ {
+ syslog(
+ LOG_NOTICE, "%.80s URL \"%.80s\" goes outside the web tree",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' resolves to a file outside the permitted web server directory tree.\n" ),
+@@ -2734,7 +2737,7 @@
+ dirp = opendir( hc->expnfilename );
+ if ( dirp == (DIR*) 0 )
+ {
+- syslog( LOG_ERR, "opendir %.80s - %m", hc->expnfilename );
++ syslog( LOG_ERR, "opendir %.80s - %m", httpd_log_escape( hc->expnfilename ) );
+ httpd_send_err( hc, 404, err404title, "", err404form, hc->encodedurl );
+ return -1;
+ }
+@@ -2974,7 +2977,8 @@
+
+ /* Parent process. */
+ closedir( dirp );
+- syslog( LOG_DEBUG, "spawned indexing process %d for directory '%.200s'", r, hc->expnfilename );
++ syslog( LOG_DEBUG, "spawned indexing process %d for directory '%.200s'",
++ r, httpd_log_escape( hc->expnfilename ) );
+ #ifdef CGI_TIMELIMIT
+ /* Schedule a kill for the child process, in case it runs too long */
+ client_data.i = r;
+@@ -3563,7 +3567,7 @@
+ (void) execve( binary, argp, envp );
+
+ /* Something went wrong. */
+- syslog( LOG_ERR, "execve %.80s - %m", hc->expnfilename );
++ syslog( LOG_ERR, "execve %.80s - %m", httpd_log_escape( hc->expnfilename ) );
+ httpd_send_err( hc, 500, err500title, "", err500form, hc->encodedurl );
+ httpd_write_response( hc );
+ _exit( 1 );
+@@ -3602,7 +3606,8 @@
+ }
+
+ /* Parent process. */
+- syslog( LOG_DEBUG, "spawned CGI process %d for file '%.200s'", r, hc->expnfilename );
++ syslog( LOG_DEBUG, "spawned CGI process %d for file '%.200s'",
++ r, httpd_log_escape( hc->expnfilename ) );
+ #ifdef CGI_TIMELIMIT
+ /* Schedule a kill for the child process, in case it runs too long */
+ client_data.i = r;
+@@ -3654,7 +3659,7 @@
+ syslog(
+ LOG_INFO,
+ "%.80s URL \"%.80s\" resolves to a non world-readable file",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' resolves to a file that is not world-readable.\n" ),
+@@ -3709,7 +3714,7 @@
+ syslog(
+ LOG_INFO,
+ "%.80s URL \"%.80s\" tried to index a directory with indexing disabled",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' resolves to a directory that has indexing disabled.\n" ),
+@@ -3729,7 +3734,7 @@
+ #else /* GENERATE_INDEXES */
+ syslog(
+ LOG_INFO, "%.80s URL \"%.80s\" tried to index a directory",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' is a directory, and directory indexing is disabled on this server.\n" ),
+@@ -3757,7 +3762,7 @@
+ syslog(
+ LOG_INFO,
+ "%.80s URL \"%.80s\" resolves to a non-world-readable index file",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' resolves to an index file that is not world-readable.\n" ),
+@@ -3786,7 +3791,7 @@
+ syslog(
+ LOG_NOTICE,
+ "%.80s URL \"%.80s\" tried to retrieve an auth file",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' is an authorization file, retrieving it is not permitted.\n" ),
+@@ -3801,7 +3806,7 @@
+ syslog(
+ LOG_NOTICE,
+ "%.80s URL \"%.80s\" tried to retrieve an auth file",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' is an authorization file, retrieving it is not permitted.\n" ),
+@@ -3828,7 +3833,7 @@
+ {
+ syslog(
+ LOG_NOTICE, "%.80s URL \"%.80s\" is executable but isn't CGI",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' resolves to a file which is marked executable but is not a CGI file; retrieving it is forbidden.\n" ),
+@@ -3839,7 +3844,7 @@
+ {
+ syslog(
+ LOG_INFO, "%.80s URL \"%.80s\" has pathinfo but isn't CGI",
+- httpd_ntoa( &hc->client_addr ), hc->encodedurl );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( hc->encodedurl ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "The requested URL '%.80s' resolves to a file plus CGI-style pathinfo, but the file is not a valid CGI file.\n" ),
+@@ -3904,12 +3909,65 @@
+ }
+
+
++/* Copy src into dst, replacing control characters with \xHH. The request
++** line, the headers and anything derived from them reach the log exactly as
++** the client sent them, so without this a request can write terminal escape
++** sequences into the log.
++*/
++static char*
++log_escape( char* dst, size_t dstsize, const char* src )
++ {
++ static const char hex[] = "0123456789abcdef";
++ size_t i = 0;
++ unsigned char c;
++
++ if ( src == (const char*) 0 )
++ src = "";
++ for ( ; *src != '\0' && i + 4 < dstsize; ++src )
++ {
++ c = (unsigned char) *src;
++ if ( c < 0x20 || c == 0x7f )
++ {
++ dst[i++] = '\\';
++ dst[i++] = 'x';
++ dst[i++] = hex[c >> 4];
++ dst[i++] = hex[c & 0xf];
++ }
++ else
++ dst[i++] = c;
++ }
++ dst[i] = '\0';
++ return dst;
++ }
++
++
++/* The same, for use straight in a syslog() argument list. Returns a pointer
++** into a small ring of buffers so that more than one value can be escaped in
++** one call. thttpd is single-threaded, so this is safe.
++*/
++char*
++httpd_log_escape( const char* src )
++ {
++ static char bufs[4][1000];
++ static int next = 0;
++ char* dst;
++
++ dst = bufs[next];
++ next = ( next + 1 ) % 4;
++ return log_escape( dst, sizeof(bufs[0]), src );
++ }
++
++
+ static void
+ make_log_entry( httpd_conn* hc, struct timeval* nowP )
+ {
+ char* ru;
+ char url[305];
+ char bytes[40];
++ char eurl[305 * 4];
++ char eref[200 * 4 + 1];
++ char eua[200 * 4 + 1];
++ char eru[80 * 4 + 1];
+
+ if ( hc->hs->no_log )
+ return;
+@@ -3922,7 +3980,7 @@
+
+ /* Format remote user. */
+ if ( hc->remoteuser[0] != '\0' )
+- ru = hc->remoteuser;
++ ru = log_escape( eru, sizeof(eru), hc->remoteuser );
+ else
+ ru = "-";
+ /* If we're vhosting, prepend the hostname to the url. This is
+@@ -3937,6 +3995,9 @@
+ else
+ (void) my_snprintf( url, sizeof(url),
+ "%.200s", hc->encodedurl );
++ (void) log_escape( eurl, sizeof(eurl), url );
++ (void) log_escape( eref, sizeof(eref), hc->referrer );
++ (void) log_escape( eua, sizeof(eua), hc->useragent );
+ /* Format the bytes. */
+ if ( hc->bytes_sent >= 0 )
+ (void) my_snprintf(
+@@ -3985,8 +4046,8 @@
+ (void) fprintf( hc->hs->logfp,
+ "%.80s - %.80s [%s] \"%.80s %.300s %.80s\" %d %s \"%.200s\" \"%.200s\"\n",
+ httpd_ntoa( &hc->client_addr ), ru, date,
+- httpd_method_str( hc->method ), url, hc->protocol,
+- hc->status, bytes, hc->referrer, hc->useragent );
++ httpd_method_str( hc->method ), eurl, hc->protocol,
++ hc->status, bytes, eref, eua );
+ #ifdef FLUSH_LOG_EVERY_TIME
+ (void) fflush( hc->hs->logfp );
+ #endif
+@@ -3995,8 +4056,8 @@
+ syslog( LOG_INFO,
+ "%.80s - %.80s \"%.80s %.200s %.80s\" %d %s \"%.200s\" \"%.200s\"",
+ httpd_ntoa( &hc->client_addr ), ru,
+- httpd_method_str( hc->method ), url, hc->protocol,
+- hc->status, bytes, hc->referrer, hc->useragent );
++ httpd_method_str( hc->method ), eurl, hc->protocol,
++ hc->status, bytes, eref, eua );
+ }
+
+
+@@ -4023,7 +4084,9 @@
+ cp = "";
+ syslog(
+ LOG_INFO, "%.80s non-local referrer \"%.80s%.80s\" \"%.80s\"",
+- httpd_ntoa( &hc->client_addr ), cp, hc->encodedurl, hc->referrer );
++ httpd_ntoa( &hc->client_addr ), httpd_log_escape( cp ),
++ httpd_log_escape( hc->encodedurl ),
++ httpd_log_escape( hc->referrer ) );
+ httpd_send_err(
+ hc, 403, err403title, "",
+ ERROR_FORM( err403form, "You must supply a local referrer to get URL '%.80s' from this server.\n" ),
+--- libhttpd.h.orig
++++ libhttpd.h
+@@ -263,6 +263,12 @@
+ extern char* httpd_err408form;
+ extern char* httpd_err503title;
+ extern char* httpd_err503form;
++
++/* Escape control characters in a string for the log, so that a request
++** cannot write terminal escape sequences into it. Returns a pointer into
++** a small ring of static buffers.
++*/
++char* httpd_log_escape( const char* src );
+
+ /* Generate a string representation of a method number. */
+ char* httpd_method_str( int method );
+--- thttpd.c.orig
++++ thttpd.c
+@@ -1778,7 +1778,8 @@
+ ** And ECONNRESET isn't interesting either.
+ */
+ if ( errno != EPIPE && errno != EINVAL && errno != ECONNRESET )
+- syslog( LOG_ERR, "write - %m sending %.80s", hc->encodedurl );
++ syslog( LOG_ERR, "write - %m sending %.80s",
++ httpd_log_escape( hc->encodedurl ) );
+ clear_connection( c, tvP );
+ return;
+ }
Index: www/thttpd/patches/patch-CVE-2012-5640
===================================================================
RCS file: www/thttpd/patches/patch-CVE-2012-5640
diff -N www/thttpd/patches/patch-CVE-2012-5640
--- /dev/null
+++ www/thttpd/patches/patch-CVE-2012-5640
@@ -0,0 +1,82 @@
+$NetBSD$
+
+CVE-2012-5640 -- denial of service. crypt() returns NULL for a salt it
+does not recognise (glibc and illumos do; NetBSD and current Linux
+return "*0" instead). thttpd passes the result straight on in all three
+places it calls crypt(), and the salt comes from a user-written
+.htpasswd, so one malformed line is enough.
+
+In auth_check2() the result is handed to strcmp(), so a request for the
+protected directory crashes the server. Note that the fix must keep
+going to the send_authenticate() call below rather than returning
+straight away: this function documents -1 as "unauthorized" and every
+existing -1 is preceded by send_authenticate(), and the callers take -1
+to mean a response has already been written. Returning -1 without it
+would answer the request with nothing at all. Fedora and Alpine carry
+this fix in the shorter "return -1" form, which has that effect. A
+syslog line is added because an unusable salt is an administrator's
+mistake, not a wrong password.
+
+In extras/htpasswd.c the result is passed to fprintf("%s"), so writing a
+password with a salt crypt() dislikes dereferences NULL. Fedora and
+Alpine guard this one too.
+
+ACME lists a crypt() NULL check for the unreleased 2.30.
+
+--- libhttpd.c.orig
++++ libhttpd.c
+@@ -1030,6 +1030,7 @@
+ FILE* fp;
+ char line[500];
+ char* cryp;
++ char* cryp2;
+ static char* prevauthpath;
+ static size_t maxprevauthpath = 0;
+ static time_t prevmtime;
+@@ -1082,8 +1083,16 @@
+ sb.st_mtime == prevmtime &&
+ strcmp( authinfo, prevuser ) == 0 )
+ {
+- /* Yes. Check against the cached encrypted password. */
+- if ( strcmp( crypt( authpass, prevcryp ), prevcryp ) == 0 )
++ /* Yes. Check against the cached encrypted password. crypt() returns
++ ** NULL for a salt it does not understand, and the password file is
++ ** user-supplied, so a bad line must not be dereferenced. Treat it as
++ ** a mismatch so that the send_authenticate() below still runs: the
++ ** callers take -1 to mean a response has already been sent.
++ */
++ cryp = crypt( authpass, prevcryp );
++ if ( cryp == (char*) 0 )
++ syslog( LOG_ERR, "unusable password for %.80s in %.80s", authinfo, authpath );
++ if ( cryp != (char*) 0 && strcmp( cryp, prevcryp ) == 0 )
+ {
+ /* Ok! */
+ httpd_realloc_str(
+@@ -1131,8 +1140,11 @@
+ {
+ /* Yes. */
+ (void) fclose( fp );
+- /* So is the password right? */
+- if ( strcmp( crypt( authpass, cryp ), cryp ) == 0 )
++ /* So is the password right? As above, crypt() may return NULL. */
++ cryp2 = crypt( authpass, cryp );
++ if ( cryp2 == (char*) 0 )
++ syslog( LOG_ERR, "unusable password for %.80s in %.80s", line, authpath );
++ if ( cryp2 != (char*) 0 && strcmp( cryp2, cryp ) == 0 )
+ {
+ /* Ok! */
+ httpd_realloc_str(
+--- extras/htpasswd.c.orig
++++ extras/htpasswd.c
+@@ -131,6 +131,11 @@
+ (void) srandom( (int) time( (time_t*) 0 ) );
+ to64( &salt[0], random(), 2 );
+ cpw = crypt( pw, salt );
++ if ( cpw == (char*) 0 )
++ {
++ (void) fprintf( stderr, "htpasswd: crypt() could not hash the password\n" );
++ exit( 1 );
++ }
+ (void) fprintf( f, "%s:%s\n", user, cpw );
+ }
+
Index: www/thttpd/patches/patch-Makefile.in
===================================================================
RCS file: www/thttpd/patches/patch-Makefile.in
diff -N www/thttpd/patches/patch-Makefile.in
--- /dev/null
+++ www/thttpd/patches/patch-Makefile.in
@@ -0,0 +1,59 @@
+$NetBSD$
+
+Install into the pkgsrc layout instead of the upstream defaults: the
+CGI programs go to libexec/cgi-bin and the sample web root to
+share/thttpd, rather than under $prefix/www.
+
+Use the BSD_INSTALL_* tools rather than "mkdir -p" and an install(1)
+run with a hardcoded owner of bin:bin, so that DESTDIR and the
+unprivileged build both work.
+
+CFLAGS is appended to rather than assigned, so that the flags pkgsrc
+passes in survive.
+
+--- Makefile.in.orig 2005-05-20 19:10:24.000000000 +0000
++++ Makefile.in
+@@ -34,7 +34,7 @@
+ # Pathname of directory to install the man page.
+ MANDIR = @mandir@
+ # Pathname of directory to install the CGI programs.
+-WEBDIR = $(prefix)/www
++WEBDIR = $(prefix)/share/thttpd
+
+ # CONFIGURE: The group that the web directory belongs to. This is so that
+ # the makeweb program can be installed set-group-id to that group, and make
+@@ -42,7 +42,7 @@
+ WEBGROUP = www
+
+ # CONFIGURE: Directory for CGI executables.
+-CGIBINDIR = $(WEBDIR)/cgi-bin
++CGIBINDIR = $(prefix)/libexec/cgi-bin
+
+ # You shouldn't need to edit anything below here.
+
+@@ -50,7 +50,7 @@
+ CCOPT = @V_CCOPT@
+ DEFS = @DEFS@
+ INCLS = -I.
+-CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
++CFLAGS += $(CCOPT) $(DEFS) $(INCLS)
+ LDFLAGS = @LDFLAGS@
+ LIBS = @LIBS@
+ NETLIBS = @V_NETLIBS@
+@@ -109,12 +109,12 @@
+ install: installthis install-man installsubdirs
+
+ installthis:
+- -mkdir -p $(DESTDIR)$(BINDIR)
+- $(INSTALL) -m 555 -o bin -g bin thttpd $(DESTDIR)$(BINDIR)
++ $(BSD_INSTALL_PROGRAM_DIR) $(DESTDIR)$(BINDIR)
++ $(BSD_INSTALL_PROGRAM) thttpd $(DESTDIR)$(BINDIR)
+
+ install-man:
+- -mkdir -p $(DESTDIR)$(MANDIR)/man8
+- $(INSTALL) -m 444 -o bin -g bin thttpd.8 $(DESTDIR)$(MANDIR)/man8
++ $(BSD_INSTALL_DATA_DIR) $(DESTDIR)$(MANDIR)/man8
++ $(BSD_INSTALL_MAN) thttpd.8 $(DESTDIR)$(MANDIR)/man8
+
+ installsubdirs:
+ for i in $(SUBDIRS) ; do ( \
Index: www/thttpd/patches/patch-cgi-src_Makefile.in
===================================================================
RCS file: www/thttpd/patches/patch-cgi-src_Makefile.in
diff -N www/thttpd/patches/patch-cgi-src_Makefile.in
--- /dev/null
+++ www/thttpd/patches/patch-cgi-src_Makefile.in
@@ -0,0 +1,46 @@
+$NetBSD$
+
+The same as patch-ab for the CGI programs: honour DESTDIR, install with
+the BSD_INSTALL_* tools instead of cp, and append to CFLAGS rather than
+overwrite it.
+
+--- cgi-src/Makefile.in.orig 2005-05-20 19:10:25.000000000 +0000
++++ cgi-src/Makefile.in
+@@ -34,7 +34,7 @@
+ CCOPT = @V_CCOPT@
+ DEFS = @DEFS@
+ INCLS = -I..
+-CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
++CFLAGS += $(CCOPT) $(DEFS) $(INCLS)
+ LDFLAGS = @LDFLAGS@ @V_STATICFLAG@
+ LIBS = @LIBS@
+ NETLIBS = @V_NETLIBS@
+@@ -67,17 +67,17 @@
+ cd .. ; $(MAKE) $(MFLAGS) strerror.o
+
+ install: all
+- -mkdir -p $(CGIBINDIR)
+- rm -f $(CGIBINDIR)/redirect
+- cp redirect $(CGIBINDIR)/redirect
+- rm -f $(MANDIR)/man8/redirect.8
+- cp redirect.8 $(MANDIR)/man8/redirect.8
+- rm -f $(CGIBINDIR)/ssi
+- cp ssi $(CGIBINDIR)/ssi
+- rm -f $(MANDIR)/man8/ssi.8
+- cp ssi.8 $(MANDIR)/man8/ssi.8
+- rm -f $(CGIBINDIR)/phf
+- cp phf $(CGIBINDIR)/phf
++ -mkdir -p $(DESTDIR)$(CGIBINDIR)
++ rm -f $(DESTDIR)$(CGIBINDIR)/redirect
++ $(BSD_INSTALL_PROGRAM) redirect $(DESTDIR)$(CGIBINDIR)/redirect
++ rm -f $(DESTDIR)$(MANDIR)/man8/redirect.8
++ $(BSD_INSTALL_MAN) redirect.8 $(DESTDIR)$(MANDIR)/man8/redirect.8
++ rm -f $(DESTDIR)$(CGIBINDIR)/ssi
++ $(BSD_INSTALL_PROGRAM) ssi $(DESTDIR)$(CGIBINDIR)/ssi
++ rm -f $(DESTDIR)$(MANDIR)/man8/ssi.8
++ $(BSD_INSTALL_MAN) ssi.8 $(DESTDIR)$(MANDIR)/man8/ssi.8
++ rm -f $(DESTDIR)$(CGIBINDIR)/phf
++ $(BSD_INSTALL_PROGRAM) phf $(DESTDIR)$(CGIBINDIR)/phf
+
+ clean:
+ rm -f $(CLEANFILES)
Index: www/thttpd/patches/patch-configure
===================================================================
RCS file: www/thttpd/patches/patch-configure
diff -N www/thttpd/patches/patch-configure
--- /dev/null
+++ www/thttpd/patches/patch-configure
@@ -0,0 +1,49 @@
+$NetBSD$
+
+Not a CVE: the configure script's test programs declare main() without a
+return type. C99 removed implicit int and current compilers reject it,
+so the very first test -- "checking whether the C compiler works" --
+fails and configure stops with "C compiler cannot create executables".
+gcc 14 and clang 16 and later are in that state; this was measured with
+clang 21 and it is what breaks the build on Debian 13.
+
+Fedora and MacPorts both carry this fix.
+
+--- configure.orig
++++ configure
+@@ -761,7 +761,7 @@
+ #line 762 "configure"
+ #include "confdefs.h"
+
+-main(){return(0);}
++int main(){return(0);}
+ EOF
+ if { (eval echo configure:767: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+@@ -880,7 +880,7 @@
+ echo $ac_n "(cached) $ac_c" 1>&6
+ else
+ ac_cv_lbl_static_flag=unknown
+- echo 'main() {}' > conftest.c
++ echo 'int main() {}' > conftest.c
+ if test "$GCC" != yes ; then
+ trial_flag="-Bstatic"
+ test=`$CC $trial_flag -o conftest conftest.c 2>&1`
+@@ -1588,7 +1588,7 @@
+ #include "confdefs.h"
+
+ int main() {
+-main()
++int main()
+ ; return 0; }
+ EOF
+ if { (eval echo configure:1595: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+@@ -2095,7 +2095,7 @@
+ #endif
+
+ int
+-main()
++int main()
+ {
+ char *data, *data2, *data3;
+ int i, pagesize;
Index: www/thttpd/patches/patch-extras_Makefile.in
===================================================================
RCS file: www/thttpd/patches/patch-extras_Makefile.in
diff -N www/thttpd/patches/patch-extras_Makefile.in
--- /dev/null
+++ www/thttpd/patches/patch-extras_Makefile.in
@@ -0,0 +1,51 @@
+$NetBSD$
+
+The same two things as patch-aa, for the helper programs: honour
+DESTDIR, install with the BSD_INSTALL_* tools instead of cp, and append
+to CFLAGS rather than overwrite it.
+
+syslogtocern is a shell script, so it goes in with BSD_INSTALL_SCRIPT.
+
+The upstream rule also made makeweb set-group-id here; that is left to
+the administrator instead, which is what README.pkgsrc explains.
+
+--- extras/Makefile.in.orig 2005-05-20 19:10:25.000000000 +0000
++++ extras/Makefile.in
+@@ -35,7 +35,7 @@
+ CCOPT = @V_CCOPT@
+ DEFS = @DEFS@
+ INCLS = -I..
+-CFLAGS = $(CCOPT) $(DEFS) $(INCLS)
++CFLAGS += $(CCOPT) $(DEFS) $(INCLS)
+ STATICFLAG = @V_STATICFLAG@
+ LDFLAGS = @LDFLAGS@
+ LIBS = @LIBS@
+@@ -66,18 +66,16 @@
+
+
+ install: all
+- rm -f $(BINDIR)/makeweb $(BINDIR)/htpasswd $(BINDIR)/syslogtocern
+- cp makeweb $(BINDIR)/makeweb
+- chgrp $(WEBGROUP) $(BINDIR)/makeweb
+- chmod 2755 $(BINDIR)/makeweb
+- cp htpasswd $(BINDIR)/htpasswd
+- cp syslogtocern $(BINDIR)/syslogtocern
+- rm -f $(MANDIR)/man1/makeweb.1
+- cp makeweb.1 $(MANDIR)/man1/makeweb.1
+- rm -f $(MANDIR)/man1/htpasswd.1
+- cp htpasswd.1 $(MANDIR)/man1/htpasswd.1
+- rm -f $(MANDIR)/man8/syslogtocern.8
+- cp syslogtocern.8 $(MANDIR)/man8/syslogtocern.8
++ rm -f $(DESTDIR)$(BINDIR)/makeweb $(DESTDIR)$(BINDIR)/htpasswd $(DESTDIR)$(BINDIR)/syslogtocern
++ $(BSD_INSTALL_PROGRAM) makeweb $(DESTDIR)$(BINDIR)/makeweb
++ $(BSD_INSTALL_PROGRAM) htpasswd $(DESTDIR)$(BINDIR)/htpasswd
++ $(BSD_INSTALL_SCRIPT) syslogtocern $(DESTDIR)$(BINDIR)/syslogtocern
++ rm -f $(DESTDIR)$(MANDIR)/man1/makeweb.1
++ $(BSD_INSTALL_MAN) makeweb.1 $(DESTDIR)$(MANDIR)/man1/makeweb.1
++ rm -f $(DESTDIR)$(MANDIR)/man1/htpasswd.1
++ $(BSD_INSTALL_MAN) htpasswd.1 $(DESTDIR)$(MANDIR)/man1/htpasswd.1
++ rm -f $(DESTDIR)$(MANDIR)/man8/syslogtocern.8
++ $(BSD_INSTALL_MAN) syslogtocern.8 $(DESTDIR)$(MANDIR)/man8/syslogtocern.8
+
+ clean:
+ rm -f $(CLEANFILES)
Index: www/thttpd/patches/patch-extras_htpasswd.c
===================================================================
RCS file: www/thttpd/patches/patch-extras_htpasswd.c
diff -N www/thttpd/patches/patch-extras_htpasswd.c
--- /dev/null
+++ www/thttpd/patches/patch-extras_htpasswd.c
@@ -0,0 +1,70 @@
+$NetBSD$
+
+Not a CVE, two things in the htpasswd utility.
+
+The line buffers are MAX_STRING_LEN (256) while a .htpasswd line is
+"user:hash". The hash of a modern crypt(3) runs to about a hundred
+characters, so a line written by any other tool does not fit, and
+my_getline() truncates at the limit without saying so; the remainder is
+then read as the next line. Reading an existing file in order to add a
+user to it therefore corrupted it. FreeBSD ports, Debian and Fedora all
+enlarge these buffers.
+
+fgets() is not checked when the password comes in on stdin, so pass is
+left uninitialised if it fails, and a leading NUL byte leaves strlen()
+at 0; either way pass[strlen(pass)-1] reads before the buffer. Both
+paths fire under AddressSanitizer on the routine extracted unchanged
+from 2.29 (empty stdin, and a line starting with a NUL byte). No other
+packaging fixes this one.
+
+--- extras/htpasswd.c.orig
++++ extras/htpasswd.c
+@@ -20,6 +20,12 @@
+ #define CR 13
+
+ #define MAX_STRING_LEN 256
++/* A .htpasswd line is "user:hash". The hash of a modern crypt(3) is around a
++** hundred characters, so a line does not fit in MAX_STRING_LEN. my_getline()
++** truncates silently at its limit and the remainder is then read as the next
++** line, so reading an existing file to update it corrupted it.
++*/
++#define MAX_LINE_LEN (MAX_STRING_LEN + 1 + 256)
+
+ int tfd;
+ char temp_template[] = "/tmp/htp.XXXXXX";
+@@ -112,8 +118,13 @@
+
+ if ( ! isatty( fileno( stdin ) ) )
+ {
+- (void) fgets( pass, sizeof(pass), stdin );
+- if ( pass[strlen(pass) - 1] == '\n' )
++ /* fgets() can fail, leaving pass uninitialised, and a NUL byte on
++ ** stdin leaves strlen() at 0; either way pass[strlen(pass)-1] would
++ ** read before the buffer.
++ */
++ if ( fgets( pass, sizeof(pass), stdin ) == (char*) 0 )
++ pass[0] = '\0';
++ if ( pass[0] != '\0' && pass[strlen(pass) - 1] == '\n' )
+ pass[strlen(pass) - 1] = '\0';
+ pw = pass;
+ }
+@@ -149,8 +160,8 @@
+ int main(int argc, char *argv[]) {
+ FILE *tfp,*f;
+ char user[MAX_STRING_LEN];
+- char line[MAX_STRING_LEN];
+- char l[MAX_STRING_LEN];
++ char line[MAX_LINE_LEN];
++ char l[MAX_LINE_LEN];
+ char w[MAX_STRING_LEN];
+ char command[MAX_STRING_LEN];
+ int found;
+@@ -188,7 +199,7 @@
+ user[sizeof(user)-1] = '\0';
+
+ found = 0;
+- while(!(my_getline(line,MAX_STRING_LEN,f))) {
++ while(!(my_getline(line,MAX_LINE_LEN,f))) {
+ if(found || (line[0] == '#') || (!line[0])) {
+ putline(tfp,line);
+ continue;
Index: www/thttpd/patches/patch-index.html
===================================================================
RCS file: www/thttpd/patches/patch-index.html
diff -N www/thttpd/patches/patch-index.html
--- /dev/null
+++ www/thttpd/patches/patch-index.html
@@ -0,0 +1,18 @@
+$NetBSD$
+
+Add the NetBSD logo to the sample index page. The image it points at
+is sitedrivenby.gif, which the package fetches as a second distfile and
+installs beside this page in share/thttpd.
+
+--- index.html.orig 2005-05-13 20:20:35.000000000 +0000
++++ index.html
+@@ -9,6 +9,9 @@
+
+ <P>
+ Here's a link to the <A HREF="http://www.acme.com/software/thttpd/">thttpd web pages</A>.
++<A HREF="http://www.netbsd.org/">
++<IMG ALIGN=RIGHT SRC="sitedrivenby.gif" border=0 ALT="Site driven by NetBSD">
++</A>
+
+ </BODY>
+ </HTML>
Index: www/thttpd/patches/patch-libhttpd.c
===================================================================
RCS file: www/thttpd/patches/patch-libhttpd.c
diff -N www/thttpd/patches/patch-libhttpd.c
--- /dev/null
+++ www/thttpd/patches/patch-libhttpd.c
@@ -0,0 +1,44 @@
+$NetBSD$
+
+Not a security fix, and not an underflow. The stock code
+
+ i = strlen( hc->origfilename ) - strlen( hc->pathinfo );
+ if ( i > 0 && strcmp( &hc->origfilename[i], hc->pathinfo ) == 0 )
+ hc->origfilename[i - 1] = '\0';
+
+already prevents the index from going negative: the "i > 0" test means
+origfilename[i-1] is only reached with i >= 1. I checked this after
+mistaking it for the same shape as the underflows in
+patch-CVE-2007-0158; it is not one.
+
+What it does change is behaviour. When PATH_INFO is the whole of
+origfilename (i == 0) the stock code leaves origfilename alone, so the
+pathinfo part is not removed from it as the comment above it says it
+should be. This makes that case set origfilename to the empty string.
+FreeBSD ports and Debian both carry the same change; Debian files it
+under "path-info" rather than as a security patch, which is the right
+reading.
+
+Included because the neighbouring CVE patches touch the same file and a
+reader will otherwise wonder why this one spot is left as it is. Drop
+this patch if the behaviour change is not wanted -- the CVE patches do
+not depend on it.
+
+--- libhttpd.c.orig
++++ libhttpd.c
+@@ -2351,8 +2351,13 @@
+ {
+ int i;
+ i = strlen( hc->origfilename ) - strlen( hc->pathinfo );
+- if ( i > 0 && strcmp( &hc->origfilename[i], hc->pathinfo ) == 0 )
+- hc->origfilename[i - 1] = '\0';
++ if ( i >= 0 && strcmp( &hc->origfilename[i], hc->pathinfo ) == 0 )
++ {
++ if ( i == 0 )
++ hc->origfilename[0] = '\0';
++ else
++ hc->origfilename[i - 1] = '\0';
++ }
+ }
+
+ /* If the expanded filename is an absolute path, check that it's still
Index: www/thttpd/patches/patch-mmc.c
===================================================================
RCS file: www/thttpd/patches/patch-mmc.c
diff -N www/thttpd/patches/patch-mmc.c
--- /dev/null
+++ www/thttpd/patches/patch-mmc.c
@@ -0,0 +1,27 @@
+$NetBSD$
+
+Turn off mmap on NetBSD up to 1.5L (__NetBSD_Version__ 105120000) and
+include <sys/param.h> so that version is defined.
+
+Before UBC arrived in 1.5L, mmap and read were not kept in sync, so
+thttpd went on serving the old contents of a page after it had been
+edited until it was restarted. From PR pkg/25487, where Hauke Fath
+reported it on 1.5.4 and Michael Santos wrote this hunk.
+
+--- mmc.c.orig 2015-11-05 18:13:49.000000000 +0000
++++ mmc.c
+@@ -37,6 +37,14 @@
+ #include <fcntl.h>
+ #include <syslog.h>
+ #include <errno.h>
++
++#if defined(__NetBSD__)
++#include <sys/param.h>
++#endif
++
++#if (defined(__NetBSD__) && __NetBSD_Version__ <= 105120000)
++#undef HAVE_MMAP
++#endif
+
+ #ifdef HAVE_MMAP
+ #include <sys/mman.h>
Index: www/thttpd/patches/patch-thttpd.c
===================================================================
RCS file: www/thttpd/patches/patch-thttpd.c
diff -N www/thttpd/patches/patch-thttpd.c
--- /dev/null
+++ www/thttpd/patches/patch-thttpd.c
@@ -0,0 +1,67 @@
+$NetBSD$
+
+Not a CVE: the access log is created world-readable. Both places that
+open it use fopen(logfile, "a"), so a log that does not exist yet is
+created 0666 & ~umask -- 0644 under the usual umask. Every line holds
+the request line, the Referer and the User-Agent, and on an
+authenticated directory the remote user name, so it should not be
+readable by every local user. This matters most after log rotation,
+where the file is gone and thttpd recreates it on SIGHUP.
+
+Created with 0640 instead. open() rather than a chmod() after fopen()
+so that there is no window in which the file exists with the wider
+mode, and so that a log the administrator already created keeps the
+mode they chose -- a chmod() would overwrite it on every start.
+
+FreeBSD ports and Fedora both fix this, but with a chmod() after the
+fopen(): FreeBSD to 0640, Fedora to 0600. Fedora additionally disables
+the fchown() below, which stops thttpd handing the log to the user it
+drops privileges to, so it cannot re-open the log afterwards. The
+fchown() is left alone here.
+
+--- thttpd.c.orig
++++ thttpd.c
+@@ -327,6 +327,25 @@
+ }
+
+
++/* Open the log file for appending. A log that has to be created is created
++** without the world-readable bit: every line holds the request, the Referer
++** and the User-Agent, and on an authenticated directory the remote user name.
++** A file that already exists keeps the mode the administrator gave it. This
++** uses open() rather than fopen() so that there is no window in which the
++** file exists with the wider mode.
++*/
++static FILE*
++open_logfile( char* lf )
++ {
++ int fd;
++
++ fd = open( lf, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP );
++ if ( fd < 0 )
++ return (FILE*) 0;
++ return fdopen( fd, "a" );
++ }
++
++
+ static void
+ re_open_logfile( void )
+ {
+@@ -339,7 +358,7 @@
+ if ( logfile != (char*) 0 && strcmp( logfile, "-" ) != 0 )
+ {
+ syslog( LOG_NOTICE, "re-opening logfile" );
+- logfp = fopen( logfile, "a" );
++ logfp = open_logfile( logfile );
+ if ( logfp == (FILE*) 0 )
+ {
+ syslog( LOG_CRIT, "re-opening %.80s - %m", logfile );
+@@ -428,7 +447,7 @@
+ logfp = stdout;
+ else
+ {
+- logfp = fopen( logfile, "a" );
++ logfp = open_logfile( logfile );
+ if ( logfp == (FILE*) 0 )
+ {
+ syslog( LOG_CRIT, "%.80s - %m", logfile );
Index: www/thttpd/files/README.pkgsrc
===================================================================
RCS file: www/thttpd/files/README.pkgsrc
diff -N www/thttpd/files/README.pkgsrc
--- /dev/null
+++ www/thttpd/files/README.pkgsrc
@@ -0,0 +1,16 @@
+makeweb and the web group
+=========================
+
+makeweb lets a user create a public_html directory under the web root.
+To do that it has to be set-group-id to the group that owns the web
+root; pkgsrc installs it without that bit, because making a program
+set-group-id is the administrator's decision, not the package's.
+
+If you want to use it:
+
+ chgrp <group> @PREFIX@/sbin/makeweb
+ chmod 2755 @PREFIX@/sbin/makeweb
+
+The group thttpd's own Makefile suggests is "www".
+
+If you do not use makeweb, leave it as it is.
Index: doc/pkg-vulnerabilities
===================================================================
RCS file: /cvsroot/pkgsrc/doc/pkg-vulnerabilities,v
retrieving revision 1.794
diff -u -r1.794 pkg-vulnerabilities
--- doc/pkg-vulnerabilities
+++ doc/pkg-vulnerabilities
@@ -1559,7 +1559,7 @@
gdk-pixbuf<0.22.0nb6 arbitrary-code-execution https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-3186
acid-[0-9]* cross-site-scripting http://secunia.com/advisories/17552/
acid-[0-9]* sql-injection http://secunia.com/advisories/17552/
-thttpd<2.25bnb4 insecure-temp-files http://secunia.com/advisories/17454/
+thttpd<2.29nb1 insecure-temp-files https://nvd.nist.gov/vuln/detail/CVE-2005-3124
rar-linux<3.5.1 format-string http://secunia.com/advisories/17524/
rar-linux<3.5.1 buffer-overflow http://secunia.com/advisories/17524/
gaim-encryption<2.39 denial-of-service https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2005-4693
@@ -6151,7 +6151,7 @@
ap{2,22}-modsecurity{,2}<2.6.6 remote-security-bypass http://secunia.com/advisories/49576/
apache-roller<5.0.1 cross-site-scripting http://secunia.com/advisories/49593/
mini_httpd-[0-9]* escape-sequence-injection https://nvd.nist.gov/vuln/detail/CVE-2009-4490
-thttpd-[0-9]* escape-sequence-injection https://nvd.nist.gov/vuln/detail/CVE-2009-4491
+thttpd<2.29nb1 escape-sequence-injection https://nvd.nist.gov/vuln/detail/CVE-2009-4491
wordpress<3.4.1 multiple-vulnerabilities http://wordpress.org/news/2012/06/wordpress-3-4-1/
typo3<4.5.17 cross-site-scripting https://typo3.org/teams/security/security-bulletins/typo3-core/typo3-core-sa-2012-003/
typo3>=4.6.0<4.6.10 cross-site-scripting https://typo3.org/teams/security/security-bulletins/typo3-core/typo3-core-sa-2012-003/
@@ -18469,7 +18469,7 @@
quagga-[0-9]* denial-of-service https://nvd.nist.gov/vuln/detail/CVE-2012-5521
ruby{22,24,25,26}-net-ldap<0.16.2 weak-cryptography https://nvd.nist.gov/vuln/detail/CVE-2014-0083
tahoe-lafs<1.8.3 arbitrary-file-deletion https://nvd.nist.gov/vuln/detail/CVE-2011-3617
-thttpd-[0-9]* denial-of-service https://nvd.nist.gov/vuln/detail/CVE-2012-5640
+thttpd<2.29nb1 denial-of-service https://nvd.nist.gov/vuln/detail/CVE-2012-5640
vsftpd<2.3.5 privilege-escalation https://nvd.nist.gov/vuln/detail/CVE-2011-2523
wide-dhcpv6-[0-9]* shell-command-injection https://nvd.nist.gov/vuln/detail/CVE-2011-2717
xscreensaver<5.14 authentication-bypass https://nvd.nist.gov/vuln/detail/CVE-2011-2187
@@ -18700,7 +18700,7 @@
matio-[0-9]* denial-of-service https://nvd.nist.gov/vuln/detail/CVE-2019-20019
matio-[0-9]* stack-overflow https://nvd.nist.gov/vuln/detail/CVE-2019-20020
upx-[0-9]* heap-overflow https://nvd.nist.gov/vuln/detail/CVE-2019-20021
-thttpd-[0-9]* buffer-underflow https://nvd.nist.gov/vuln/detail/CVE-2007-0158
+thttpd<2.29nb1 buffer-underflow https://nvd.nist.gov/vuln/detail/CVE-2007-0158
upx-[0-9]* denial-of-service https://nvd.nist.gov/vuln/detail/CVE-2019-20051
upx-[0-9]* denial-of-service https://nvd.nist.gov/vuln/detail/CVE-2019-20053
libsixel<1.8.5 denial-of-service https://nvd.nist.gov/vuln/detail/CVE-2019-20056
Home |
Main Index |
Thread Index |
Old Index