[hamradio-commits] [dump1090] 01/02: add upstream fd leak patch and stop the local http service from serving files. Add support for moving the web interface to Apache2

Matthew Ernisse mernisse-guest at moszumanska.debian.org
Thu Oct 23 14:58:53 UTC 2014


This is an automated email from the git hooks/post-receive script.

mernisse-guest pushed a commit to branch master
in repository dump1090.

commit d2d0f59431a9c3a3ba45a8988f1bc90a8cb81f7c
Author: Matthew Ernisse <mernisse at ub3rgeek.net>
Date:   Wed Oct 22 14:08:13 2014 -0400

    add upstream fd leak patch and stop the local http service from serving files.  Add support for moving the web interface to Apache2
---
 debian/README.http                                 |  30 ++++
 debian/apache2.conf                                |  13 ++
 debian/changelog                                   |   9 ++
 debian/control                                     |   1 +
 debian/docs                                        |   1 +
 debian/dump1090.examples                           |   1 +
 debian/patches/04-socket_leak.patch                | 155 +++++++++++++++++++++
 .../05-disable-local-file-http-access.patch        |  89 ++++++++++++
 debian/patches/series                              |   2 +
 9 files changed, 301 insertions(+)

diff --git a/debian/README.http b/debian/README.http
new file mode 100644
index 0000000..515d85e
--- /dev/null
+++ b/debian/README.http
@@ -0,0 +1,30 @@
+dump1090 HTTP interface
+=======================
+
+The stock dump1090 provides a HTTP interface that is served from the same
+network code that handles all the network communication into and out of the
+daemon.  This feature has been disabled in the Debian build due to the 
+complexity of auditing and maintaing the code.  The web interface is still
+included and can be served by a HTTP daemon such as Apache2.
+
+A sample Apache2 configuration file suitable for modification is provided in 
+/usr/share/doc/dump1090/examples.
+
+Most users can get the web interface running by:
+
+1) Install Apache2
+$ sudo apt-get install apache2
+
+2) Enable the proxy and proxy_http module:
+$ sudo a2enmod proxy_http
+
+3) Copy the sample configuration and modify as needed.
+$ sudo cp /usr/share/doc/dump1090/examples/apache2.conf \
+  /etc/apache2/conf.d/dump1090.conf
+$ sudoedit /etc/apache2/conf.d/dump1090.conf
+
+4) Restart Apache
+$ sudo invoke-rc.d apache2 restart
+
+5) Browse to your system at http://<your dump1090 host>/dump1090/
+
diff --git a/debian/apache2.conf b/debian/apache2.conf
new file mode 100644
index 0000000..bb3d40f
--- /dev/null
+++ b/debian/apache2.conf
@@ -0,0 +1,13 @@
+Alias /dump1090 /usr/share/dump1090/public_html
+
+<Directory /usr/share/dump1090/public_html/>
+	Options +FollowSymLinks
+	AllowOverride All
+	Order Allow,Deny
+	Allow From All
+	DirectoryIndex gmap.html
+</Directory>
+
+<IfModule mod_proxy_http.c>
+	ProxyPass /dump1090/data.json http://127.0.0.1:8080/dump1090/data.json
+</IfModule>
diff --git a/debian/changelog b/debian/changelog
index 0dde8b6..14c8c16 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,12 @@
+dump1090 (1.09.1007.14+dfsg-4) unstable; urgency=medium
+
+  * Apply PR#33 from upstream.  This fixes a segfault and possible file
+    descriptor exhaustion in the network code.
+  * Disable local filesystem access in the HTTP server.
+  * Update FSF address in copyright.
+
+ -- Matthew Ernisse <mernisse at ub3rgeek.net>  Tue, 21 Oct 2014 23:46:33 -0400
+
 dump1090 (1.09.1007.14+dfsg-3) unstable; urgency=low
 
   * Replace shipped version of excanvas.js with libjs-excanvas
diff --git a/debian/control b/debian/control
index 9b0cb80..39637f7 100644
--- a/debian/control
+++ b/debian/control
@@ -12,6 +12,7 @@ Vcs-Browser: http://anonscm.debian.org/cgit/pkg-hamradio/dump1090.git
 Package: dump1090
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}, libjs-excanvas, libjs-jquery-ui, librtlsdr0
+Suggests: apache2
 Description: Mode S decoder specifically designed for RTLSDR devices
  The main features are:
   * Robust decoding of weak messages, with mode1090 many users observed
diff --git a/debian/docs b/debian/docs
index 6f77277..d75088e 100644
--- a/debian/docs
+++ b/debian/docs
@@ -1,2 +1,3 @@
 README.md
 TODO
+debian/README.http
diff --git a/debian/dump1090.examples b/debian/dump1090.examples
index 609db9f..16ce511 100644
--- a/debian/dump1090.examples
+++ b/debian/dump1090.examples
@@ -1,2 +1,3 @@
+debian/apache2.conf
 tools/*
 testfiles/*
diff --git a/debian/patches/04-socket_leak.patch b/debian/patches/04-socket_leak.patch
new file mode 100644
index 0000000..699d7be
--- /dev/null
+++ b/debian/patches/04-socket_leak.patch
@@ -0,0 +1,155 @@
+Description: Ensure socket fds are cleaned up after the connection is closed.
+.
+This affected HTTP connections which create a new conection every second for
+each browser-client; after a while no new network connections could be made
+to dump1090.
+.
+(Although not mentioned in the commit messages, it also fixes a bug which would
+segfault when accessing closed, deallocated send-sockets (modesSendAllClients)
+which were not written to, and then opening a read-socket (modesReadFromClient)
+the socket would be automatically freed by modesFreeClient, and then 
+modesReadFromClients would try accessing the freed client struct, segfaulting
+the program. This was corrected by adding the modesCloseClient function, which
+closes the client connection and marks it as invalid, and clients are only
+actually freed later).
+.
+Patch originally by hhm <heehooman+vcs-ci at gmail.com>, modified for the Debian
+packaging by Matthew Ernisse <mernisse at ub3rgeek.net>
+Origin: https://github.com/MalcolmRobb/dump1090/pull/33/files
+Forwarded: https://github.com/MalcolmRobb/dump1090/pull/33
+--- a/net_io.c
++++ b/net_io.c
+@@ -162,8 +162,16 @@
+         }
+     }
+ 
+-    // It's now safe to remove this client
+-    close(c->fd);
++    free(c);
++}
++
++//
++//=========================================================================
++//
++// Close the client connection and mark it as closed
++//
++void modesCloseClient(struct client *c) {
++        close(c->fd);
+     if (c->service == Modes.sbsos) {
+         if (Modes.stat_sbs_connections) Modes.stat_sbs_connections--;
+     } else if (c->service == Modes.ros) {
+@@ -175,8 +183,9 @@
+     if (Modes.debug & MODES_DEBUG_NET)
+         printf("Closing client %d\n", c->fd);
+ 
+-    free(c);
++    c->fd = -1;
+ }
++
+ //
+ //=========================================================================
+ //
+@@ -189,15 +198,20 @@
+         // Read next before servicing client incase the service routine deletes the client! 
+         struct client *next = c->next;
+ 
+-        if (c->service == service) {
++        if (c->fd != -1) {
++            if (c->service == service) {
+ #ifndef _WIN32
+-            int nwritten = write(c->fd, msg, len);
++                int nwritten = write(c->fd, msg, len);
+ #else
+-            int nwritten = send(c->fd, msg, len, 0 );
++                int nwritten = send(c->fd, msg, len, 0);
+ #endif
+-            if (nwritten != len) {
+-                modesFreeClient(c);
++                if (nwritten != len) {
++                    modesFreeClient(c);
++                }
+             }
++        } else {
++            modesFreeClient(c);
++            modesCloseClient(c);
+         }
+         c = next;
+     }
+@@ -870,6 +884,10 @@
+         nread = recv(c->fd, c->buf+c->buflen, left, 0);
+         if (nread < 0) {errno = WSAGetLastError();}
+ #endif
++        if (nread == 0) {
++            modesCloseClient(c);
++            return;
++        }
+ 
+         // If we didn't get all the data we asked for, then return once we've processed what we did get.
+         if (nread != left) {
+@@ -880,7 +898,7 @@
+ #else
+         if ( (nread < 0) && (errno != EWOULDBLOCK)) { // Error, or end of file
+ #endif
+-            modesFreeClient(c);
++            modesCloseClient(c);
+             return;
+         }
+         if (nread <= 0) {
+@@ -929,6 +947,7 @@
+                 // Have a 0x1a followed by 1, 2 or 3 - pass message less 0x1a to handler.
+                 if (handler(c, s)) {
+                     modesFreeClient(c);
++                    modesCloseClient(c);
+                     return;
+                 }
+                 fullmsg = 1;
+@@ -942,12 +961,17 @@
+             // in the buffer, note that we full-scan the buffer at every read for simplicity.
+             //
+             while ((e = strstr(s, sep)) != NULL) { // end of first message if found
+-                *e = '\0';                         // The handler expects null terminated strings
++                *e = '\0';                         // The handler expects null
++                                                   // terminated strings
+                 if (handler(c, s)) {               // Pass message to handler.
+-                    modesFreeClient(c);            // Handler returns 1 on error to signal we .
+-                    return;                        // should close the client connection
++                    modesFreeClient(c);            // Handler returns 1 on
++                                                   // error to signal we should
++                                                   // should close the client
++                                                   // connection
++                    modesCloseClient(c);
+                 }
+-                s = e + strlen(sep);               // Move to start of next message
++                s = e + strlen(sep);               // Move to start of next
++                                                   // message.
+                 fullmsg = 1;
+             }
+         }
+@@ -971,15 +995,20 @@
+     struct client *c = modesAcceptClients();
+ 
+     while (c) {
+-        // Read next before servicing client incase the service routine deletes the client! 
++        // Read next before servicing client incase the service routine
++        // deletes the client!
+         struct client *next = c->next;
+ 
+-        if (c->service == Modes.ris) {
+-            modesReadFromClient(c,"\n",decodeHexMessage);
+-        } else if (c->service == Modes.bis) {
+-            modesReadFromClient(c,"",decodeBinMessage);
+-        } else if (c->service == Modes.https) {
+-            modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest);
++        if (c->fd >= 0) {
++            if (c->service == Modes.ris) {
++                modesReadFromClient(c,"\n",decodeHexMessage);
++            } else if (c->service == Modes.bis) {
++                modesReadFromClient(c,"",decodeBinMessage);
++            } else if (c->service == Modes.https) {
++                modesReadFromClient(c,"\r\n\r\n",handleHTTPRequest);
++            }
++        } else {
++            modesFreeClient(c);
+         }
+         c = next;
+     }
diff --git a/debian/patches/05-disable-local-file-http-access.patch b/debian/patches/05-disable-local-file-http-access.patch
new file mode 100644
index 0000000..f6a0944
--- /dev/null
+++ b/debian/patches/05-disable-local-file-http-access.patch
@@ -0,0 +1,89 @@
+Description: Disable local file serving from the internal HTTP server.
+Author: Matthew John Ernisse <mernisse at ub3rgeek.net>
+Forwarded: no
+
+--- a/net_io.c
++++ b/net_io.c
+@@ -704,9 +704,7 @@
+ #define HTTP_OK "200 OK";
+ #define HTTP_NOTFOUND "404 Not Found";
+ #define MODES_CONTENT_TYPE_HTML "text/html;charset=utf-8"
+-#define MODES_CONTENT_TYPE_CSS  "text/css;charset=utf-8"
+ #define MODES_CONTENT_TYPE_JSON "application/json;charset=utf-8"
+-#define MODES_CONTENT_TYPE_JS   "application/javascript;charset=utf-8"
+ //
+ // Get an HTTP request header and write the response to the client.
+ // gain here we assume that the socket buffer is enough without doing
+@@ -722,8 +720,6 @@
+     int httpver, keepalive;
+     char *url, *content;
+     char ctype[48];
+-    char getFile[1024];
+-    char *ext;
+ 
+     if (Modes.debug & MODES_DEBUG_NET)
+         printf("\nHTTP request: %s\n", c->buf);
+@@ -751,55 +747,17 @@
+         printf("HTTP requested URL: %s\n\n", url);
+     }
+     
+-    if (strlen(url) < 2) {
+-        snprintf(getFile, sizeof getFile, "%s/gmap.html", HTMLPATH); // Default file
+-    } else {
+-        snprintf(getFile, sizeof getFile, "%s/%s", HTMLPATH, url);
+-    }
+-
+-    // Select the content to send, we have just two so far:
+-    // "/" -> Our google map application.
+-    // "/data.json" -> Our ajax request to update planes.
++    /* Removed local file access from the HTTP service.  We are only serving
++     * data.json now.  Anything else will return a 404.
++     */
+     if (strstr(url, "/data.json")) {
+         content = aircraftsToJson(&clen);
+-        //snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JSON);
++        snprintf(ctype, sizeof(ctype), MODES_CONTENT_TYPE_JSON);
+     } else {
+-        struct stat sbuf;
+-        int fd = -1;
+-
+-        if (stat(getFile, &sbuf) != -1 && (fd = open(getFile, O_RDONLY)) != -1) {
+-            content = (char *) malloc(sbuf.st_size);
+-            if (read(fd, content, sbuf.st_size) == -1) {
+-                snprintf(content, sbuf.st_size, "Error reading from %s: %s",
+-                    getFile, strerror(errno));
+-                httpcode = HTTP_NOTFOUND;
+-            }
+-            clen = sbuf.st_size;
+-        } else {
+-            char buf[128];
+-            clen = snprintf(buf, sizeof(buf), "Error opening %s: %s",
+-                getFile, strerror(errno));
+-            content = strdup(buf);
+-            httpcode = HTTP_NOTFOUND;
+-        }
+-        
+-        if (fd != -1) {
+-            close(fd);
+-        }
+-    }
+-
+-    // Get file extension and content type
+-    snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_HTML); // Default content type
+-    ext = strrchr(getFile, '.');
+-
+-    if (strlen(ext) > 0) {
+-        if (strstr(ext, ".json")) {
+-            snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JSON);
+-        } else if (strstr(ext, ".css")) {
+-            snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_CSS);
+-        } else if (strstr(ext, ".js")) {
+-            snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_JS);
+-        }
++        httpcode = HTTP_NOTFOUND
++        content = strdup("File not found.");
++        clen = strlen(content);
++        snprintf(ctype, sizeof ctype, MODES_CONTENT_TYPE_HTML);
+     }
+ 
+     // Create the header and send the reply
diff --git a/debian/patches/series b/debian/patches/series
index 64202c1..46cc347 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -2,3 +2,5 @@
 01-jquery.patch
 02-http-buffer.patch
 03-excanvas.patch
+04-socket_leak.patch
+05-disable-local-file-http-access.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-hamradio/dump1090.git



More information about the pkg-hamradio-commits mailing list