From b787e060780a102f3b9eeaed246b53552cfd94d6 Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Fri, 8 Mar 2002 13:46:36 +0000 Subject: [PATCH] add a bit of error checking to the mod_cgid daemon's logic to read the request over the unix socket it isn't perfect (EINTR, partial reads) but it is good enough to avoid segfaulting if some code tries to verify that cgid is active by connecting to its unix socket git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@93790 13f79535-47bb-0310-9956-ffa450edef68 --- modules/generators/mod_cgid.c | 61 ++++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index c5385af25b..7f905ce5e2 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -267,9 +267,9 @@ static void cgid_maint(int reason, void *data, apr_wait_t status) } #endif -static void get_req(int fd, request_rec *r, char **argv0, char ***env, int *req_type) +static int get_req(int fd, request_rec *r, char **argv0, char ***env, int *req_type) { - int i, len, j; + int i, len, j, rc; unsigned char *data; char **environ; core_dir_config *temp_core; @@ -278,11 +278,24 @@ static void get_req(int fd, request_rec *r, char **argv0, char ***env, int *req_ r->server = apr_pcalloc(r->pool, sizeof(server_rec)); - read(fd, req_type, sizeof(int)); - read(fd, &j, sizeof(int)); - read(fd, &len, sizeof(int)); + rc = read(fd, req_type, sizeof(int)); + if (rc != sizeof(int)) { + return 1; + } + rc = read(fd, &j, sizeof(int)); + if (rc != sizeof(int)) { + return 1; + } + rc = read(fd, &len, sizeof(int)); + if (rc != sizeof(int)) { + return 1; + } + data = apr_pcalloc(r->pool, len + 1); /* get a cleared byte for final '\0' */ - i = read(fd, data, len); + rc = read(fd, data, len); + if (rc != len) { + return 1; + } r->filename = ap_getword(r->pool, (const char **)&data, '\n'); *argv0 = ap_getword(r->pool, (const char **)&data, '\n'); @@ -297,7 +310,10 @@ static void get_req(int fd, request_rec *r, char **argv0, char ***env, int *req_ *env = environ; r->args = ap_getword(r->pool, (const char **)&data, '\n'); - read(fd, &i, sizeof(int)); + rc = read(fd, &i, sizeof(int)); + if (rc != sizeof(int)) { + return 1; + } /* add 1, so that if i == 0, we still malloc something. */ @@ -310,10 +326,22 @@ static void get_req(int fd, request_rec *r, char **argv0, char ***env, int *req_ if (suexec_mod) { suexec_config_t *suexec_cfg = apr_pcalloc(r->pool, sizeof(*suexec_cfg)); - read(fd, &i, sizeof(int)); - read(fd, &suexec_cfg->ugid.uid, sizeof(uid_t)); - read(fd, &suexec_cfg->ugid.gid, sizeof(gid_t)); - read(fd, &suexec_cfg->active, sizeof(int)); + rc = read(fd, &i, sizeof(int)); + if (rc != sizeof(int)) { + return 1; + } + rc = read(fd, &suexec_cfg->ugid.uid, sizeof(uid_t)); + if (rc != sizeof(uid_t)) { + return 1; + } + rc = read(fd, &suexec_cfg->ugid.gid, sizeof(gid_t)); + if (rc != sizeof(gid_t)) { + return 1; + } + rc = read(fd, &suexec_cfg->active, sizeof(int)); + if (rc != sizeof(int)) { + return 1; + } dconf[i] = (void *)suexec_cfg; } @@ -357,6 +385,8 @@ static void get_req(int fd, request_rec *r, char **argv0, char ***env, int *req_ * seg fault. */ r->notes = apr_table_make(r->pool, 1); + + return 0; } @@ -543,7 +573,14 @@ static int cgid_server(void *data) r = apr_pcalloc(ptrans, sizeof(request_rec)); procnew = apr_pcalloc(ptrans, sizeof(*procnew)); r->pool = ptrans; - get_req(sd2, r, &argv0, &env, &req_type); + rc = get_req(sd2, r, &argv0, &env, &req_type); + if (rc) { + ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, + main_server, + "Error reading request on cgid socket"); + close(sd2); + continue; + } apr_os_file_put(&r->server->error_log, &errfileno, 0, r->pool); apr_os_file_put(&inout, &sd2, 0, r->pool); -- 2.40.0