From c49f671caccaccd44f3f08f5d782e0c81b20653e Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Thu, 16 Apr 2009 19:23:45 +0000 Subject: [PATCH] mod_cgid: Improve handling of long AF_UNIX socket names (ScriptSock). Dynamically allocate the AF_UNIX sockaddr based on the required filename size. For some platforms (e.g., Solaris, OS X, FreeBSD), this allows longer socket filenames to be used. When the name is too long, the failure reporting is more consistent and a socket with truncated pathname is not left stranded. The user still needs to use ScriptSock to specify a shorter name. An extra unlink() failure message may be generated when attempting to clean up the socket after a daemon initialization error; the message is surpressed for ENOTENT, but not for ENAMETOOLONG. PR: 47037 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@765725 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ modules/generators/mod_cgid.c | 25 ++++++++++++------------- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 609747febc..0fb733fc34 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.3.3 + *) mod_cgid: Improve handling of long AF_UNIX socket names (ScriptSock). + PR 47037. [Jeff Trawick] + *) SECURITY: CVE-2008-5519 (cve.mitre.org) mod_proxy_ajp: Avoid delivering content from a previous request which failed to send a request body. PR 46949 [Ruediger Pluem] diff --git a/modules/generators/mod_cgid.c b/modules/generators/mod_cgid.c index 84b33bcdba..557a237437 100644 --- a/modules/generators/mod_cgid.c +++ b/modules/generators/mod_cgid.c @@ -88,6 +88,8 @@ static int daemon_should_exit = 0; static server_rec *root_server = NULL; static apr_pool_t *root_pool = NULL; static const char *sockname; +static struct sockaddr_un *server_addr; +static apr_socklen_t server_addr_len; static pid_t parent_pid; static ap_unix_identity_t empty_ugid = { (uid_t)-1, (gid_t)-1, -1 }; @@ -591,10 +593,8 @@ static void cgid_child_errfn(apr_pool_t *pool, apr_status_t err, static int cgid_server(void *data) { - struct sockaddr_un unix_addr; int sd, sd2, rc; mode_t omask; - apr_socklen_t len; apr_pool_t *ptrans; server_rec *main_server = data; apr_hash_t *script_hash = apr_hash_make(pcgi); @@ -619,12 +619,8 @@ static int cgid_server(void *data) return errno; } - memset(&unix_addr, 0, sizeof(unix_addr)); - unix_addr.sun_family = AF_UNIX; - apr_cpystrn(unix_addr.sun_path, sockname, sizeof unix_addr.sun_path); - omask = umask(0077); /* so that only Apache can use socket */ - rc = bind(sd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)); + rc = bind(sd, (struct sockaddr *)server_addr, server_addr_len); umask(omask); /* can't fail, so can't clobber errno */ if (rc < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, @@ -678,6 +674,8 @@ static int cgid_server(void *data) cgid_req_t cgid_req; apr_status_t stat; void *key; + apr_socklen_t len; + struct sockaddr_un unix_addr; apr_pool_clear(ptrans); @@ -906,6 +904,12 @@ static int cgid_init(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, parent_pid = getpid(); sockname = ap_server_root_relative(p, sockname); + + server_addr_len = APR_OFFSETOF(struct sockaddr_un, sun_path) + strlen(sockname); + server_addr = (struct sockaddr_un *)apr_palloc(p, server_addr_len + 1); + server_addr->sun_family = AF_UNIX; + strcpy(server_addr->sun_path, sockname); + ret = cgid_start(p, main_server, procnew); if (ret != OK ) { return ret; @@ -1158,15 +1162,10 @@ static apr_status_t close_unix_socket(void *thefd) static int connect_to_daemon(int *sdptr, request_rec *r, cgid_server_conf *conf) { - struct sockaddr_un unix_addr; int sd; int connect_tries; apr_interval_time_t sliding_timer; - memset(&unix_addr, 0, sizeof(unix_addr)); - unix_addr.sun_family = AF_UNIX; - apr_cpystrn(unix_addr.sun_path, sockname, sizeof unix_addr.sun_path); - connect_tries = 0; sliding_timer = 100000; /* 100 milliseconds */ while (1) { @@ -1175,7 +1174,7 @@ static int connect_to_daemon(int *sdptr, request_rec *r, return log_scripterror(r, conf, HTTP_INTERNAL_SERVER_ERROR, errno, "unable to create socket to cgi daemon"); } - if (connect(sd, (struct sockaddr *)&unix_addr, sizeof(unix_addr)) < 0) { + if (connect(sd, (struct sockaddr *)server_addr, server_addr_len) < 0) { if (errno == ECONNREFUSED && connect_tries < DEFAULT_CONNECT_ATTEMPTS) { ap_log_rerror(APLOG_MARK, APLOG_DEBUG, errno, r, "connect #%d to cgi daemon failed, sleeping before retry", -- 2.40.0