NetBSD Problem Report #50655
From www@NetBSD.org Wed Jan 13 14:25:22 2016
Return-Path: <www@NetBSD.org>
Received: from mail.netbsd.org (mail.NetBSD.org [199.233.217.200])
(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))
(Client CN "mail.netbsd.org", Issuer "Postmaster NetBSD.org" (verified OK))
by mollari.NetBSD.org (Postfix) with ESMTPS id E9CDD7A210
for <gnats-bugs@gnats.NetBSD.org>; Wed, 13 Jan 2016 14:25:21 +0000 (UTC)
Message-Id: <20160113142520.96CA27ACCB@mollari.NetBSD.org>
Date: Wed, 13 Jan 2016 14:25:20 +0000 (UTC)
From: steffen@sdaoden.eu
Reply-To: steffen@sdaoden.eu
To: gnats-bugs@NetBSD.org
Subject: bozohttpd can be hung infinitely in SSL mode
X-Send-Pr-Version: www-1.0
>Number: 50655
>Category: bin
>Synopsis: bozohttpd can be hung infinitely in SSL mode
>Confidential: no
>Severity: serious
>Priority: high
>Responsible: mrg
>State: closed
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Jan 13 14:30:00 +0000 2016
>Closed-Date: Fri Apr 05 18:21:54 +0000 2019
>Last-Modified: Tue Jun 11 09:45:01 +0000 2019
>Originator: Steffen
>Release: current
>Organization:
>Environment:
any
>Description:
Try "telnet ADDRESS 80" that bozohttpd serves without SSL and then enter a space. Wait a minute. Then do the same on "443" via SSL and notice the difference.
Despite having no alarm, other tested servers simply close a connection without a HTTP timeout indication if no data was ever received.
So different to the patch etc. that shattered my nerves in private the one below doesn't do anything else but fixing the first issue and adjusting the second, too.
Thank you.
>How-To-Repeat:
See above
>Fix:
Add an alarm to avoid "infinite" SSL accept waits..
When doing
?0[sdaoden@wales tmp]$ time telnet www.XXX.eu 443
Trying XXX.XXX.XXX.XXX...
Connected to www.XXX.eu.
Escape character is '^]'.
and typing just a single character then no TCP timeout comes into
play, and since no socket timeout is set and SSL_accept() doesn't
know about timeouts the connection would stuck forever:
^C
Connection closed by foreign host.
9m27.94s real 0m0.01s user 0m0.02s system
Therefore export a portion of the existing alarm facility and use
it to ensure that MAX_WAIT_TIME is honoured also for the SSL
handshake phase.
---
bozohttpd.c | 29 ++++++++++++++++++++---------
bozohttpd.h | 14 ++++++++++----
ssl-bozo.c | 8 ++++++--
3 files changed, 36 insertions(+), 15 deletions(-)
diff --git a/bozohttpd.c b/bozohttpd.c
index 0ef800e..49b59ba 100644
--- a/bozohttpd.c
+++ b/bozohttpd.c
@@ -146,7 +146,6 @@
#include <netdb.h>
#include <pwd.h>
#include <grp.h>
-#include <signal.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
@@ -165,7 +164,7 @@
#define LOG_FTP LOG_DAEMON
#endif
-volatile sig_atomic_t alarmhit;
+volatile sig_atomic_t bozo_alarmhit;
/*
* check there's enough space in the prefs and names arrays.
@@ -368,7 +367,7 @@ bozo_clean_request(bozo_httpreq_t *request)
static void
alarmer(int sig)
{
- alarmhit = 1;
+ bozo_alarmhit = 1;
}
/*
@@ -563,8 +562,6 @@ bozo_read_request(bozohttpd_t *httpd)
*/
if (bozo_daemon_fork(httpd))
return NULL;
- if (bozo_ssl_accept(httpd))
- return NULL;
request = bozomalloc(httpd, sizeof(*request));
memset(request, 0, sizeof(*request));
@@ -635,12 +632,26 @@ bozo_read_request(bozohttpd_t *httpd)
sa.sa_flags = 0;
sigaction(SIGALRM, &sa, NULL);
+ if (bozo_has_ssl(httpd)) {
+ alarm(MAX_WAIT_TIME);
+
+ /* Simply close connection if the SSL handshake fails */
+ if (bozo_ssl_accept(httpd)) {
+ alarm(0);
+ goto cleanup;
+ }
+ }
+
alarm(MAX_WAIT_TIME);
- while ((str = bozodgetln(httpd, STDIN_FILENO, &len, bozo_read)) != NULL) {
+
+ while ((str = bozodgetln(httpd, STDIN_FILENO, &len, bozo_read))
+ != NULL) {
alarm(0);
- if (alarmhit) {
- (void)bozo_http_error(httpd, 408, NULL,
- "request timed out");
+ if (bozo_alarmhit) {
+ /* Don't use HTML if no data was ever seen */
+ if (line > 0)
+ (void)bozo_http_error(httpd, 408, NULL,
+ "request timed out");
goto cleanup;
}
line++;
diff --git a/bozohttpd.h b/bozohttpd.h
index 41f271f..629d4c4 100644
--- a/bozohttpd.h
+++ b/bozohttpd.h
@@ -29,17 +29,19 @@
* SUCH DAMAGE.
*
*/
-#ifndef BOZOHTTOPD_H_
-#define BOZOHTTOPD_H_ 1
+#ifndef BOZOHTTPD_H_
+#define BOZOHTTPD_H_ 1
#include "netbsd_queue.h"
#include <sys/stat.h>
+#include <signal.h>
+#include <stdio.h>
+
#ifndef NO_LUA_SUPPORT
#include <lua.h>
#endif
-#include <stdio.h>
/* QNX provides a lot of NetBSD things in nbutil.h */
#ifdef HAVE_NBUTIL_H
@@ -205,6 +207,8 @@ typedef struct bozoprefs_t {
#define DEBUG_OBESE 3
#define DEBUG_EXPLODING 4
+extern volatile sig_atomic_t bozo_alarmhit;
+
#define strornull(x) ((x) ? (x) : "<null>")
#if defined(__GNUC__) && __GNUC__ >= 3
@@ -247,12 +251,14 @@ char *bozostrdup(bozohttpd_t *, bozo_httpreq_t *, const char *);
/* ssl-bozo.c */
#ifdef NO_SSL_SUPPORT
+#define bozo_has_ssl(x) (0)
#define bozo_ssl_set_opts(w, x, y) bozo_noop
#define bozo_ssl_set_ciphers(w, x, y) bozo_noop
#define bozo_ssl_init(x) bozo_noop
#define bozo_ssl_accept(x) (0)
#define bozo_ssl_destroy(x) bozo_noop
#else
+# define bozo_has_ssl(x) ((x)->sslinfo != NULL)
void bozo_ssl_set_opts(bozohttpd_t *, const char *, const char *);
void bozo_ssl_set_ciphers(bozohttpd_t *, const char *);
void bozo_ssl_init(bozohttpd_t *);
@@ -366,4 +372,4 @@ bozoheaders_t *addmerge_replheader(bozo_httpreq_t *, const char *,
int bozo_set_pref(bozohttpd_t *, bozoprefs_t *, const char *, const char *);
char *bozo_get_pref(bozoprefs_t *, const char *);
-#endif /* BOZOHTTOPD_H_ */
+#endif /* BOZOHTTPD_H_ */
diff --git a/ssl-bozo.c b/ssl-bozo.c
index 3cf8727..4297ed7 100644
--- a/ssl-bozo.c
+++ b/ssl-bozo.c
@@ -269,8 +269,12 @@ bozo_ssl_accept(bozohttpd_t *httpd)
SSL_set_rfd(sslinfo->bozossl, 0);
SSL_set_wfd(sslinfo->bozossl, 1);
- const int ret = SSL_accept(sslinfo->bozossl);
- bozo_check_error_queue(httpd, "accept", ret);
+ int ret = SSL_accept(sslinfo->bozossl);
+ if (bozo_alarmhit == 0) {
+ if (ret <= 0)
+ bozo_check_error_queue(httpd, "accept", ret);
+ } else
+ ret = 0;
return ret != 1;
}
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->feedback
State-Changed-By: mrg@NetBSD.org
State-Changed-When: Thu, 28 Feb 2019 08:28:58 +0000
State-Changed-Why:
i've commited a fix for this to current, and will request pullups
to supported releases in the near future.
Responsible-Changed-From-To: bin-bug-people->mrg
Responsible-Changed-By: mrg@NetBSD.org
Responsible-Changed-When: Thu, 28 Feb 2019 08:29:13 +0000
Responsible-Changed-Why:
i handled it.
From: "matthew green" <mrg@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50655 CVS commit: src/libexec/httpd
Date: Thu, 28 Feb 2019 08:28:22 +0000
Module Name: src
Committed By: mrg
Date: Thu Feb 28 08:28:22 UTC 2019
Modified Files:
src/libexec/httpd: auth-bozo.c bozohttpd.8 bozohttpd.c bozohttpd.h
dir-index-bozo.c ssl-bozo.c
Log Message:
add ssl specific timeout value (30s). if SSL_accept() doesn't
work with in this timeout value, ssl setup now fails.
mostly different from, but inspired from the patch in PR 50655
To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/libexec/httpd/auth-bozo.c
cvs rdiff -u -r1.78 -r1.79 src/libexec/httpd/bozohttpd.8
cvs rdiff -u -r1.111 -r1.112 src/libexec/httpd/bozohttpd.c
cvs rdiff -u -r1.58 -r1.59 src/libexec/httpd/bozohttpd.h
cvs rdiff -u -r1.31 -r1.32 src/libexec/httpd/dir-index-bozo.c
cvs rdiff -u -r1.25 -r1.26 src/libexec/httpd/ssl-bozo.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
From: Steffen Nurpmeso <steffen@sdaoden.eu>
To: gnats-bugs@gnats.netbsd.org
Cc:
Subject: Re: bin/50655 - serious high priority sw-bug
Date: Fri, 05 Apr 2019 19:58:48 +0200
Hi.
I get "feedback messages" for this PR, but have not used bozohttpd
ever since. Maybe i should try again, but for one i am very, very
happy with lighttpd which works absolutely seemless also ever
since, except for one bug which has been fixed almost instantly
once it has been reported, and then it will take a long time --
months -- until i find time for a day or so to reiterate what was
going on and verifying that it has been fixed. I have seen the
commit changeset, and i did not like that there are now two
different socket timeouts. I do not think that Mr. Green requires
feedback on that issue beside that.
--steffen
|
|Der Kragenbaer, The moon bear,
|der holt sich munter he cheerfully and one by one
|einen nach dem anderen runter wa.ks himself off
|(By Robert Gernhardt)
State-Changed-From-To: feedback->closed
State-Changed-By: mrg@NetBSD.org
State-Changed-When: Fri, 05 Apr 2019 18:21:54 +0000
State-Changed-Why:
two socket timeouts doesn't really matter, they whole system hasa
global timeout, and if any part moves forward, it only resets the
local part. bozohttpd is still very liberal in its timeouts
compared to some other servers, but should handle all these types
of attacks sanely now.
thanks for the PR.
From: "matthew green" <mrg@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc:
Subject: PR/50655 CVS commit: pkgsrc/www/bozohttpd
Date: Tue, 11 Jun 2019 09:41:02 +0000
Module Name: pkgsrc
Committed By: mrg
Date: Tue Jun 11 09:41:02 UTC 2019
Modified Files:
pkgsrc/www/bozohttpd: Makefile distinfo
Log Message:
update to bozohttpd 20190228. changes include:
o extend timeout facility to ssl and stop servers hanging forever
if the client never sends anything. reported by Steffen in netbsd
PR#50655.
o don't display special files in the directory index. they aren't
served, but links to them are generated.
o fix CGI '+' parameter handling, some error checking, and a double
free. from rajeev_v_pillai@yahoo.com
o more directory indexing clean up. from rajeev_v_pillai@yahoo.com
To generate a diff of this commit:
cvs rdiff -u -r1.92 -r1.93 pkgsrc/www/bozohttpd/Makefile
cvs rdiff -u -r1.71 -r1.72 pkgsrc/www/bozohttpd/distinfo
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
>Unformatted:
(Contact us)
$NetBSD: query-full-pr,v 1.43 2018/01/16 07:36:43 maya Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2017
The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.