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:

NetBSD Home
NetBSD PR Database Search

(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.