Index: build/fixconf.sed =================================================================== --- build/fixconf.sed (revision 823071) +++ build/fixconf.sed (working copy) @@ -53,35 +53,35 @@ s/^ZombieScanInterval/FcgidZombieScanInterval/g # Next we fix all other occurences without matching # the ones, that are already OK -s/\([^D]\)BusyScanInterval/\1FcgidBusyScanInterval/g -s/\([^D]\)BusyTimeout/\1FcgidBusyTimeout/g -s/\([^D]\)DefaultInitEnv/\1FcgidInitialEnv/g -s/\([^D]\)DefaultMaxClassProcessCount/\1FcgidMaxProcessesPerClass/g -s/\([^D]\)DefaultMinClassProcessCount/\1FcgidMinProcessesPerClass/g -s/\([^D]\)ErrorScanInterval/\1FcgidErrorScanInterval/g -s/\([^D]\)FastCgiAccessChecker/\1FcgidAccessChecker/g -s/\([^D]\)FastCgiAccessCheckerAuthoritative/\1FcgidAccessCheckerAuthoritative/g -s/\([^D]\)FastCgiAuthenticator/\1FcgidAuthenticator/g -s/\([^D]\)FastCgiAuthenticatorAuthoritative/\1FcgidAuthenticatorAuthoritative/g -s/\([^D]\)FastCgiAuthorizer/\1FcgidAuthorizer/g -s/\([^D]\)FastCgiAuthorizerAuthoritative/\1FcgidAuthorizerAuthoritative/g -s/\([^D]\)FCGIWrapper/\1FcgidWrapper/g -s/\([^D]\)IdleScanInterval/\1FcgidIdleScanInterval/g -s/\([^D]\)IdleTimeout/\1FcgidIdleTimeout/g -s/\([^D]\)IPCCommTimeout/\1FcgidIOTimeout/g -s/\([^D]\)IPCConnectTimeout/\1FcgidConnectTimeout/g -s/\([^D]\)MaxProcessCount/\1FcgidMaxProcesses/g -s/\([^D]\)MaxRequestInMem/\1FcgidMaxRequestInMem/g -s/\([^D]\)MaxRequestLen/\1FcgidMaxRequestLen/g -s/\([^D]\)MaxRequestsPerProcess/\1FcgidMaxRequestsPerProcess/g -s/\([^D]\)OutputBufferSize/\1FcgidOutputBufferSize/g -s/\([^D]\)PassHeader/\1FcgidPassHeader/g -s/\([^D]\)PHP_Fix_Pathinfo_Enable/\1FcgidFixPathinfo/g -s/\([^D]\)ProcessLifeTime/\1FcgidProcessLifeTime/g -s/\([^D]\)SharememPath/\1FcgidProcessTableFile/g -s/\([^D]\)SocketPath/\1FcgidIPCDir/g -s/\([^D]\)SpawnScore/\1FcgidSpawnScore/g -s/\([^D]\)SpawnScoreUpLimit/\1FcgidSpawnScoreUpLimit/g -s/\([^D]\)TerminationScore/\1FcgidTerminationScore/g -s/\([^D]\)TimeScore/\1FcgidTimeScore/g -s/\([^D]\)ZombieScanInterval/\1FcgidZombieScanInterval/g +s/\([^d]\)BusyScanInterval/\1FcgidBusyScanInterval/g +s/\([^d]\)BusyTimeout/\1FcgidBusyTimeout/g +s/\([^d]\)DefaultInitEnv/\1FcgidInitialEnv/g +s/\([^d]\)DefaultMaxClassProcessCount/\1FcgidMaxProcessesPerClass/g +s/\([^d]\)DefaultMinClassProcessCount/\1FcgidMinProcessesPerClass/g +s/\([^d]\)ErrorScanInterval/\1FcgidErrorScanInterval/g +s/\([^d]\)FastCgiAccessChecker/\1FcgidAccessChecker/g +s/\([^d]\)FastCgiAccessCheckerAuthoritative/\1FcgidAccessCheckerAuthoritative/g +s/\([^d]\)FastCgiAuthenticator/\1FcgidAuthenticator/g +s/\([^d]\)FastCgiAuthenticatorAuthoritative/\1FcgidAuthenticatorAuthoritative/g +s/\([^d]\)FastCgiAuthorizer/\1FcgidAuthorizer/g +s/\([^d]\)FastCgiAuthorizerAuthoritative/\1FcgidAuthorizerAuthoritative/g +s/\([^d]\)FCGIWrapper/\1FcgidWrapper/g +s/\([^d]\)IdleScanInterval/\1FcgidIdleScanInterval/g +s/\([^d]\)IdleTimeout/\1FcgidIdleTimeout/g +s/\([^d]\)IPCCommTimeout/\1FcgidIOTimeout/g +s/\([^d]\)IPCConnectTimeout/\1FcgidConnectTimeout/g +s/\([^d]\)MaxProcessCount/\1FcgidMaxProcesses/g +s/\([^d]\)MaxRequestInMem/\1FcgidMaxRequestInMem/g +s/\([^d]\)MaxRequestLen/\1FcgidMaxRequestLen/g +s/\([^d]\)MaxRequestsPerProcess/\1FcgidMaxRequestsPerProcess/g +s/\([^d]\)OutputBufferSize/\1FcgidOutputBufferSize/g +s/\([^d]\)PassHeader/\1FcgidPassHeader/g +s/\([^d]\)PHP_Fix_Pathinfo_Enable/\1FcgidFixPathinfo/g +s/\([^d]\)ProcessLifeTime/\1FcgidProcessLifeTime/g +s/\([^d]\)SharememPath/\1FcgidProcessTableFile/g +s/\([^d]\)SocketPath/\1FcgidIPCDir/g +s/\([^d]\)SpawnScore/\1FcgidSpawnScore/g +s/\([^d]\)SpawnScoreUpLimit/\1FcgidSpawnScoreUpLimit/g +s/\([^d]\)TerminationScore/\1FcgidTerminationScore/g +s/\([^d]\)TimeScore/\1FcgidTimeScore/g +s/\([^d]\)ZombieScanInterval/\1FcgidZombieScanInterval/g Index: CHANGES-FCGID =================================================================== --- CHANGES-FCGID (revision 823071) +++ CHANGES-FCGID (working copy) @@ -1,4 +1,23 @@ -*- coding: utf-8 -*- +Changes with mod_fcgid 2.3.5 + + *) Fix a bug in fixconf.sed that resulted in a prefix of "FcgidFcgid" on the + updated directives. [Dan Hulme ] + + *) Fix possible corruption or truncation of request bodies which exceed + FcgidMaxRequestInMem. This is a regression since mod_fcgid 2.2, which + effectively ignored FcgidMaxRequestInMem if larger than 8K. PR 48021. + [Jeff Trawick] + + *) Fix handling of the request body when a FastCGI access checker/ + authenticator/authorizer (AAA) was configured. The body wasn't available + for the request handler. PR 47973. + [Jeff Trawick, Barry Scott ] + + *) Fix handling of FcgidCmdOptions so that it can apply to wrapper scripts + which were defined with command-line arguments on the FcgidWrapper + directive. [Jeff Trawick] + Changes with mod_fcgid 2.3.4 *) Corrected unix 'make install' target regression in 2.3.3. [Jeff Trawick] Index: docs/manual/mod/mod_fcgid.html.en =================================================================== --- docs/manual/mod/mod_fcgid.html.en (revision 823071) +++ docs/manual/mod/mod_fcgid.html.en (working copy) @@ -827,6 +827,9 @@ FcgidMinProcessesPerClass. A value of 0 disables the check.

+

This idle timeout check is performed at the frequency of the configured + FcgidIdleScanInterval.

+

This setting will apply to all applications spawned for this server or virtual host. Use FcgidCmdOptions to apply @@ -1077,6 +1080,9 @@ FcgidMinProcessesPerClass. A value of 0 disables the check.

+

This process lifetime check is performed at the frequency of the configured + FcgidIdleScanInterval.

+

This setting will apply to all applications spawned for this server or virtual host. Use FcgidCmdOptions to apply Index: docs/manual/mod/mod_fcgid.xml =================================================================== --- docs/manual/mod/mod_fcgid.xml (revision 823071) +++ docs/manual/mod/mod_fcgid.xml (working copy) @@ -778,6 +778,9 @@ FcgidMinProcessesPerClass. A value of 0 disables the check.

+

This idle timeout check is performed at the frequency of the configured + FcgidIdleScanInterval.

+

This setting will apply to all applications spawned for this server or virtual host. Use FcgidCmdOptions to apply @@ -969,6 +972,9 @@ FcgidMinProcessesPerClass. A value of 0 disables the check.

+

This process lifetime check is performed at the frequency of the configured + FcgidIdleScanInterval.

+

This setting will apply to all applications spawned for this server or virtual host. Use FcgidCmdOptions to apply Index: modules/fcgid/fcgid_proc_unix.c =================================================================== --- modules/fcgid/fcgid_proc_unix.c (revision 823071) +++ modules/fcgid/fcgid_proc_unix.c (working copy) @@ -259,6 +259,17 @@ return errno; } + /* IPC directory permissions are safe, but avoid confusion */ + /* Not all flavors of unix use the current umask for AF_UNIX perms */ + + rv = apr_file_perms_set(unix_addr.sun_path, APR_FPROT_UREAD|APR_FPROT_UWRITE|APR_FPROT_UEXECUTE); + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_CRIT, rv, main_server, + "mod_fcgid: Couldn't set permissions on unix domain socket %s", + unix_addr.sun_path); + return rv; + } + /* Listen the socket */ if (listen(unix_socket, DEFAULT_FCGID_LISTENBACKLOG) < 0) { ap_log_error(APLOG_MARK, APLOG_ERR, errno, main_server, @@ -747,8 +758,11 @@ apr_size_t len; const char* base; if ((rv = apr_bucket_read(e, &base, &len, - APR_BLOCK_READ)) != APR_SUCCESS) + APR_BLOCK_READ)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, ipc_handle->request, + "mod_fcgid: can't read request from bucket"); return rv; + } vec[nvec].iov_len = len; vec[nvec].iov_base = (char*) base; Index: modules/fcgid/fcgid_proc_win.c =================================================================== --- modules/fcgid/fcgid_proc_win.c (revision 823071) +++ modules/fcgid/fcgid_proc_win.c (working copy) @@ -59,7 +59,7 @@ return APR_SUCCESS; } -apr_status_t proc_spawn_process(char *wrapperpath, fcgid_proc_info *procinfo, +apr_status_t proc_spawn_process(char *wrapper_cmdline, fcgid_proc_info *procinfo, fcgid_procnode *procnode) { HANDLE *finish_event, listen_handle; @@ -79,7 +79,7 @@ /* Build wrapper args */ argc = 0; - tmp = wrapperpath; + tmp = wrapper_cmdline; while (1) { word = ap_getword_white(procnode->proc_pool, &tmp); if (word == NULL || *word == '\0') @@ -165,7 +165,7 @@ != APR_SUCCESS || (rv = apr_procattr_dir_set(proc_attr, ap_make_dirstr_parent(procnode->proc_pool, - (wrapperpath && wrapperpath[0] != '\0') + (wrapper_cmdline && wrapper_cmdline[0] != '\0') ? wargv[0] : procinfo->cgipath))) != APR_SUCCESS || (rv = apr_procattr_cmdtype_set(proc_attr, APR_PROGRAM)) != APR_SUCCESS @@ -184,10 +184,10 @@ } /* fork and exec now */ - if (wrapperpath != NULL && wrapperpath[0] != '\0') { + if (wrapper_cmdline != NULL && wrapper_cmdline[0] != '\0') { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, procinfo->main_server, "mod_fcgid: call %s with wrapper %s", - procinfo->cgipath, wrapperpath); + procinfo->cgipath, wrapper_cmdline); if ((rv = apr_proc_create(procnode->proc_id, wargv[0], wargv, proc_environ, proc_attr, procnode->proc_pool)) != APR_SUCCESS) { Index: modules/fcgid/fcgid_pm_main.c =================================================================== --- modules/fcgid/fcgid_pm_main.c (revision 823071) +++ modules/fcgid/fcgid_pm_main.c (working copy) @@ -531,9 +531,9 @@ } /* Spawn the process now */ - /* XXX Spawn uses wrapperpath, but log uses cgipath ? */ + /* XXX Spawn uses wrapper_cmdline, but log uses cgipath ? */ if ((rv = - proc_spawn_process(command->wrapperpath, &procinfo, + proc_spawn_process(command->wrapper_cmdline, &procinfo, procnode)) != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_WARNING, rv, main_server, "mod_fcgid: spawn process %s error", Index: modules/fcgid/fcgid_conf.c =================================================================== --- modules/fcgid/fcgid_conf.c (revision 823071) +++ modules/fcgid/fcgid_conf.c (working copy) @@ -748,8 +748,11 @@ apr_size_t cur_id; } wrapper_id_info; +/* FIXME thread safety issues when FcgidWrapper is used in .htaccess; + * see use of pconf + */ const char *set_wrapper_config(cmd_parms * cmd, void *dirconfig, - const char *wrapperpath, + const char *wrapper_cmdline, const char *extension, const char *virtual) { @@ -760,13 +763,11 @@ wrapper_id_info *id_info; apr_size_t *wrapper_id; fcgid_wrapper_conf *wrapper = NULL; + apr_pool_t *wrapper_conf_pool = cmd->server->process->pconf; /* bad */ fcgid_dir_conf *config = (fcgid_dir_conf *) dirconfig; /* Sanity checks */ - if (wrapperpath == NULL) - return "Invalid wrapper file"; - if (virtual == NULL && extension != NULL && !strcasecmp(extension, WRAPPER_FLAG_VIRTUAL)) { virtual = WRAPPER_FLAG_VIRTUAL; extension = NULL; @@ -798,21 +799,21 @@ apr_pool_cleanup_null, cmd->server->process->pool); } - /* Get wrapper_id for wrapperpath */ + /* Get wrapper_id for wrapper_cmdline */ if ((wrapper_id = - apr_hash_get(id_info->wrapper_id_hash, wrapperpath, - strlen(wrapperpath))) == NULL) { + apr_hash_get(id_info->wrapper_id_hash, wrapper_cmdline, + strlen(wrapper_cmdline))) == NULL) { wrapper_id = apr_pcalloc(cmd->server->process->pool, sizeof(*wrapper_id)); *wrapper_id = id_info->cur_id++; - apr_hash_set(id_info->wrapper_id_hash, wrapperpath, - strlen(wrapperpath), wrapper_id); + apr_hash_set(id_info->wrapper_id_hash, wrapper_cmdline, + strlen(wrapper_cmdline), wrapper_id); } - wrapper = apr_pcalloc(cmd->server->process->pconf, sizeof(*wrapper)); + wrapper = apr_pcalloc(wrapper_conf_pool, sizeof(*wrapper)); /* Get wrapper path */ - tmp = wrapperpath; + tmp = wrapper_cmdline; path = ap_getword_white(cmd->temp_pool, &tmp); if (path == NULL || *path == '\0') return "Invalid wrapper config"; @@ -823,7 +824,9 @@ return missing_file_msg(cmd->pool, "Wrapper", path, rv); } - apr_cpystrn(wrapper->args, wrapperpath, _POSIX_PATH_MAX); + wrapper->exe = apr_pstrdup(wrapper_conf_pool, path); + /* FIXME no need to embed in structure (subject to correct pool usage) */ + apr_cpystrn(wrapper->args, wrapper_cmdline, _POSIX_PATH_MAX); wrapper->inode = finfo.inode; wrapper->deviceid = finfo.device; wrapper->share_group_id = *wrapper_id; Index: modules/fcgid/fcgid_pm_win.c =================================================================== --- modules/fcgid/fcgid_pm_win.c (revision 823071) +++ modules/fcgid/fcgid_pm_win.c (working copy) @@ -140,13 +140,13 @@ command->virtualhost = r->server->server_hostname; /* Update fcgid_command with wrapper info */ - command->wrapperpath[0] = '\0'; + command->wrapper_cmdline[0] = '\0'; if ((wrapperconf = get_wrapper_info(argv0, r))) { - apr_cpystrn(command->wrapperpath, wrapperconf->args, _POSIX_PATH_MAX); + apr_cpystrn(command->wrapper_cmdline, wrapperconf->args, _POSIX_PATH_MAX); command->deviceid = wrapperconf->deviceid; command->inode = wrapperconf->inode; command->share_grp_id = wrapperconf->share_group_id; - cmd_to_spawn = command->wrapperpath; + cmd_to_spawn = wrapperconf->exe; } else { cmd_to_spawn = command->cgipath; Index: modules/fcgid/fcgid_pm_unix.c =================================================================== --- modules/fcgid/fcgid_pm_unix.c (revision 823071) +++ modules/fcgid/fcgid_pm_unix.c (working copy) @@ -411,13 +411,13 @@ command->virtualhost = r->server->server_hostname; /* Update fcgid_command with wrapper info */ - command->wrapperpath[0] = '\0'; + command->wrapper_cmdline[0] = '\0'; if ((wrapperconf = get_wrapper_info(argv0, r))) { - apr_cpystrn(command->wrapperpath, wrapperconf->args, _POSIX_PATH_MAX); + apr_cpystrn(command->wrapper_cmdline, wrapperconf->args, _POSIX_PATH_MAX); command->deviceid = wrapperconf->deviceid; command->inode = wrapperconf->inode; command->share_grp_id = wrapperconf->share_group_id; - cmd_to_spawn = command->wrapperpath; + cmd_to_spawn = wrapperconf->exe; } else { cmd_to_spawn = command->cgipath; Index: modules/fcgid/fcgid_pm.h =================================================================== --- modules/fcgid/fcgid_pm.h (revision 823071) +++ modules/fcgid/fcgid_pm.h (working copy) @@ -22,7 +22,7 @@ typedef struct { char cgipath[_POSIX_PATH_MAX]; - char wrapperpath[_POSIX_PATH_MAX]; + char wrapper_cmdline[_POSIX_PATH_MAX]; apr_ino_t inode; dev_t deviceid; apr_size_t share_grp_id; Index: modules/fcgid/fcgid_bridge.c =================================================================== --- modules/fcgid/fcgid_bridge.c (revision 823071) +++ modules/fcgid/fcgid_bridge.c (working copy) @@ -376,8 +376,6 @@ if ((rv = proc_write_ipc(&bucket_ctx->ipc, output_brigade)) != APR_SUCCESS) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, - "mod_fcgid: error writing data to FastCGI server"); bucket_ctx->has_error = 1; return HTTP_INTERNAL_SERVER_ERROR; } @@ -437,39 +435,18 @@ return cond_status; } -int bridge_request(request_rec * r, int role, const char *argv0, - fcgid_wrapper_conf * wrapper_conf) +static int add_request_body(request_rec *r, apr_pool_t *request_pool, + apr_bucket_brigade *output_brigade) { - apr_pool_t *request_pool = r->main ? r->main->pool : r->pool; - server_rec *s = r->server; - fcgid_server_conf *sconf = ap_get_module_config(s->module_config, + apr_bucket *bucket_input, *bucket_header; + apr_file_t *fd = NULL; + apr_off_t cur_pos = 0, request_size = 0; + apr_status_t rv; + FCGI_Header *stdin_request_header; + fcgid_server_conf *sconf = ap_get_module_config(r->server->module_config, &fcgid_module); - apr_status_t rv = APR_SUCCESS; int seen_eos; - apr_off_t request_size = 0; - apr_file_t *fd = NULL; - int need_truncate = 1; - apr_off_t cur_pos = 0; - FCGI_Header *stdin_request_header; - apr_bucket_brigade *output_brigade; - apr_bucket *bucket_input, *bucket_header, *bucket_eos; - char **envp = ap_create_environment(request_pool, - r->subprocess_env); - /* Create brigade for the request to fastcgi server */ - output_brigade = - apr_brigade_create(request_pool, r->connection->bucket_alloc); - - /* Build the begin request and environ request, append them to output_brigade */ - if (!build_begin_block - (role, r, r->connection->bucket_alloc, output_brigade) - || !build_env_block(r, envp, r->connection->bucket_alloc, - output_brigade)) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "mod_fcgid: can't build begin or env request"); - return HTTP_INTERNAL_SERVER_ERROR; - } - /* Stdin header and body */ /* XXX HACK: I have to read all the request into memory before sending it to fastcgi application server, this prevents slow clients from @@ -548,6 +525,15 @@ apr_pool_userdata_get(&tmp, fd_key, r->connection->pool); fd = tmp; + + if (fd != NULL) { + if ((rv = apr_file_trunc(fd, 0)) != APR_SUCCESS) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r, + "mod_fcgid: can't truncate existing " + "temporary file"); + return HTTP_INTERNAL_SERVER_ERROR; + } + } } if (fd == NULL) { @@ -574,12 +560,9 @@ apr_pool_userdata_set((const void *) fd, fd_key, apr_pool_cleanup_null, r->connection->pool); - } else if (need_truncate) { - need_truncate = 0; - apr_file_trunc(fd, 0); - cur_pos = 0; } - // Write request to tmp file + + /* Write request to tmp file */ if ((rv = apr_file_write_full(fd, (const void *) data, len, &wrote_len)) != APR_SUCCESS @@ -589,7 +572,7 @@ "mod_fcgid: can't write tmp file for stdin request"); return HTTP_INTERNAL_SERVER_ERROR; } - // Create file bucket + /* Create file bucket */ bucket_stdin = apr_bucket_file_create(fd, cur_pos, len, r->pool, r->connection->bucket_alloc); @@ -640,6 +623,40 @@ } APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_header); + return 0; +} + +int bridge_request(request_rec * r, int role, const char *argv0, + fcgid_wrapper_conf * wrapper_conf) +{ + apr_pool_t *request_pool = r->main ? r->main->pool : r->pool; + apr_bucket_brigade *output_brigade; + apr_bucket *bucket_eos; + char **envp = ap_create_environment(request_pool, + r->subprocess_env); + int rc; + + /* Create brigade for the request to fastcgi server */ + output_brigade = + apr_brigade_create(request_pool, r->connection->bucket_alloc); + + /* Build the begin request and environ request, append them to output_brigade */ + if (!build_begin_block + (role, r, r->connection->bucket_alloc, output_brigade) + || !build_env_block(r, envp, r->connection->bucket_alloc, + output_brigade)) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "mod_fcgid: can't build begin or env request"); + return HTTP_INTERNAL_SERVER_ERROR; + } + + if (role == FCGI_RESPONDER) { + rc = add_request_body(r, request_pool, output_brigade); + if (rc) { + return rc; + } + } + /* The eos bucket now */ bucket_eos = apr_bucket_eos_create(r->connection->bucket_alloc); APR_BRIGADE_INSERT_TAIL(output_brigade, bucket_eos); Index: modules/fcgid/fcgid_conf.h =================================================================== --- modules/fcgid/fcgid_conf.h (revision 823071) +++ modules/fcgid/fcgid_conf.h (working copy) @@ -54,7 +54,8 @@ } auth_conf; typedef struct { - char args[_POSIX_PATH_MAX]; + const char *exe; /* executable file path */ + char args[_POSIX_PATH_MAX]; /* entire command line */ apr_ino_t inode; apr_dev_t deviceid; apr_size_t share_group_id; Index: modules/fcgid/fcgid_proc_unix.c =================================================================== --- modules/fcgid/fcgid_proc_unix.c (revision 827986) +++ modules/fcgid/fcgid_proc_unix.c (working copy) @@ -43,6 +43,17 @@ #include "fcgid_pm.h" #include "fcgid_spawn_ctl.h" +/* apr forward compatibility */ +#ifndef APR_FPROT_UWRITE +#define APR_FPROT_UWRITE APR_UWRITE +#endif +#ifndef APR_FPROT_UREAD +#define APR_FPROT_UREAD APR_UREAD +#endif +#ifndef APR_FPROT_UEXECUTE +#define APR_FPROT_UEXECUTE APR_UEXECUTE +#endif + #if MODULE_MAGIC_NUMBER_MAJOR < 20081201 #define ap_unixd_config unixd_config // #define ap_unixd_setup_child unixd_setup_child