]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
* Do better checking of pollset operations in various places to avoid segfaults.
authorRuediger Pluem <rpluem@apache.org>
Sun, 16 Aug 2009 20:29:47 +0000 (20:29 +0000)
committerRuediger Pluem <rpluem@apache.org>
Sun, 16 Aug 2009 20:29:47 +0000 (20:29 +0000)
PR: 46467
Submitted by: Stefan Fritsch <sf sfritsch.de>
Reviewed by: rpluem

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@804764 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/generators/mod_cgi.c
modules/proxy/mod_proxy_connect.c
server/mpm/event/event.c
server/mpm/prefork/prefork.c
server/mpm/worker/worker.c

diff --git a/CHANGES b/CHANGES
index 0bbcd38acc4bb9747b8fc1f201f32b638cd9b370..6c96a6be4d42dd64c20d45f1279c379a76eca820 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
 
 Changes with Apache 2.3.3
 
+  *) Various modules: Do better checking of pollset operations in order to
+     avoid segmentation faults if they fail. PR 46467
+     [Stefan Fritsch <sf sfritsch.de>]
+
   *) mod_autoindex: Correctly create an empty cell if the description
      for a file is missing. PR 47682 [Peter Poeml <poeml suse.de>]
 
index 1d4a16370e75d9bf14816dd10aa2d2b61796f8fc..359b3baa89e36ced25542c925ef87ff0633bc0ca 100644 (file)
@@ -580,7 +580,11 @@ static apr_bucket *cgi_bucket_create(request_rec *r,
 
     /* Create the pollset */
     rv = apr_pollset_create(&data->pollset, 2, r->pool, 0);
-    AP_DEBUG_ASSERT(rv == APR_SUCCESS);
+    if (rv != APR_SUCCESS) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                     "cgi: apr_pollset_create(); check system or user limits");
+        return NULL;
+    }
 
     fd.desc_type = APR_POLL_FILE;
     fd.reqevents = APR_POLLIN;
@@ -588,12 +592,20 @@ static apr_bucket *cgi_bucket_create(request_rec *r,
     fd.desc.f = out; /* script's stdout */
     fd.client_data = (void *)1;
     rv = apr_pollset_add(data->pollset, &fd);
-    AP_DEBUG_ASSERT(rv == APR_SUCCESS);
+    if (rv != APR_SUCCESS) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                     "cgi: apr_pollset_add(); check system or user limits");
+        return NULL;
+    }
 
     fd.desc.f = err; /* script's stderr */
     fd.client_data = (void *)2;
     rv = apr_pollset_add(data->pollset, &fd);
-    AP_DEBUG_ASSERT(rv == APR_SUCCESS);
+    if (rv != APR_SUCCESS) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                     "cgi: apr_pollset_add(); check system or user limits");
+        return NULL;
+    }
 
     data->r = r;
     b->data = data;
@@ -908,6 +920,8 @@ static int cgi_handler(request_rec *r)
     apr_file_pipe_timeout_set(script_err, 0);
 
     b = cgi_bucket_create(r, script_in, script_err, c->bucket_alloc);
+    if (b == NULL)
+       return HTTP_INTERNAL_SERVER_ERROR;
 #else
     b = apr_bucket_pipe_create(script_in, c->bucket_alloc);
 #endif
index fdadc565e68bd07ed12f3e8dcf3778b4c095811f..8f55e911f38fb0ae9346ae3c2c835767dfbfe0ed 100644 (file)
@@ -268,7 +268,8 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
     if ((rv = apr_pollset_create(&pollset, 2, r->pool, 0)) != APR_SUCCESS) {
         apr_socket_close(sock);
         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
-            "proxy: CONNECT: error apr_pollset_create()");
+            "proxy: CONNECT: error apr_pollset_create();"
+            " check system or user limits");
         return HTTP_INTERNAL_SERVER_ERROR;
     }
 
@@ -278,11 +279,23 @@ static int proxy_connect_handler(request_rec *r, proxy_worker *worker,
     pollfd.reqevents = APR_POLLIN;
     pollfd.desc.s = client_socket;
     pollfd.client_data = NULL;
-    apr_pollset_add(pollset, &pollfd);
+    rv = apr_pollset_add(pollset, &pollfd);
+    if (rv != APR_SUCCESS) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                     "proxy: CONNECT: error apr_pollset_add();"
+                     " check system or user limits");
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
 
     /* Add the server side to the poll */
     pollfd.desc.s = sock;
-    apr_pollset_add(pollset, &pollfd);
+    rv = apr_pollset_add(pollset, &pollfd);
+    if (rv != APR_SUCCESS) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+                     "proxy: CONNECT: error apr_pollset_add();"
+                     " check system or user limits");
+        return HTTP_INTERNAL_SERVER_ERROR;
+    }
 
     while (1) { /* Infinite loop until error (one side closes the connection) */
         if ((rv = apr_pollset_poll(pollset, -1, &pollcnt, &signalled)) != APR_SUCCESS) {
index 630121adbc52932b3fffc6d467b1e54fcb5b193a..cb5c9427a515eaa9f011212851df6abae73b9756 100644 (file)
@@ -2444,7 +2444,8 @@ static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
         if (rv != APR_SUCCESS) {
             ap_log_error(APLOG_MARK, APLOG_CRIT, rv, NULL,
                          "Couldn't create a Thread Safe Pollset. "
-                         "Is it supported on your platform?");
+                         "Is it supported on your platform?"
+                         "Also check system or user limits!");
             return HTTP_INTERNAL_SERVER_ERROR;
         }
         apr_pollset_destroy(event_pollset);
index d1559c7997fb1808ae515818efa7594644b0fb2f..9b30635fc831ae90856c1c801302fc3af10ff90f 100644 (file)
@@ -521,8 +521,12 @@ static void child_main(int child_num_arg)
         pfd.reqevents = APR_POLLIN;
         pfd.client_data = lr;
 
-        /* ### check the status */
-        (void) apr_pollset_add(pollset, &pfd);
+        status = apr_pollset_add(pollset, &pfd);
+        if (status != APR_SUCCESS) {
+            ap_log_error(APLOG_MARK, APLOG_EMERG, status, ap_server_conf,
+                         "Couldn't add listener to pollset; check system or user limits");
+            clean_child_exit(APEXIT_CHILDSICK);
+        }
 
         lr->accept_func = ap_unixd_accept;
     }
index a5994d0c2d58241624c35bd3d83badbedb818a6a..d1ae5282547abc5e098d58830f5778310d946c9c 100644 (file)
@@ -610,8 +610,14 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t *thd, void * dummy)
 
     free(ti);
 
-    /* ### check the status */
-    (void) apr_pollset_create(&pollset, num_listensocks, tpool, 0);
+    rv = apr_pollset_create(&pollset, num_listensocks, tpool, 0);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
+                     "Couldn't create pollset in thread;"
+                     " check system or user limits");
+        /* let the parent decide how bad this really is */
+        clean_child_exit(APEXIT_CHILDSICK);
+    }
 
     for (lr = ap_listeners; lr != NULL; lr = lr->next) {
         apr_pollfd_t pfd = { 0 };
@@ -621,8 +627,14 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t *thd, void * dummy)
         pfd.reqevents = APR_POLLIN;
         pfd.client_data = lr;
 
-        /* ### check the status */
-        (void) apr_pollset_add(pollset, &pfd);
+        rv = apr_pollset_add(pollset, &pfd);
+        if (rv != APR_SUCCESS) {
+            ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf,
+                         "Couldn't create add listener to pollset;"
+                         " check system or user limits");
+            /* let the parent decide how bad this really is */
+            clean_child_exit(APEXIT_CHILDSICK);
+        }
 
         lr->accept_func = ap_unixd_accept;
     }