diff options
Diffstat (limited to 'server')
-rw-r--r-- | server/config.c | 4 | ||||
-rw-r--r-- | server/connection.c | 16 | ||||
-rw-r--r-- | server/core.c | 18 | ||||
-rw-r--r-- | server/gen_test_char.c | 4 | ||||
-rw-r--r-- | server/main.c | 33 | ||||
-rw-r--r-- | server/mpm/prefork/prefork.c | 5 | ||||
-rw-r--r-- | server/mpm_common.c | 4 | ||||
-rw-r--r-- | server/request.c | 5 | ||||
-rw-r--r-- | server/scoreboard.c | 4 | ||||
-rw-r--r-- | server/util.c | 2 | ||||
-rw-r--r-- | server/vhost.c | 18 |
11 files changed, 64 insertions, 49 deletions
diff --git a/server/config.c b/server/config.c index 7e5e06b2..8a742bfb 100644 --- a/server/config.c +++ b/server/config.c @@ -1112,11 +1112,11 @@ AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p, if (retval != NULL) return retval; - if (sub_tree == NULL && curr_parent != NULL) { + if (sub_tree == NULL) { sub_tree = *curr_parent; } - if (sub_tree == NULL && current != NULL) { + if (sub_tree == NULL) { sub_tree = *current; } } diff --git a/server/connection.c b/server/connection.c index d4880b0b..3db5a2e6 100644 --- a/server/connection.c +++ b/server/connection.c @@ -154,8 +154,20 @@ AP_DECLARE(void) ap_lingering_close(conn_rec *c) break; if (timeup == 0) { - /* First time through; calculate now + 30 seconds. */ - timeup = apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER); + /* + * First time through; + * calculate now + 30 seconds (MAX_SECS_TO_LINGER). + * + * If some module requested a shortened waiting period, only wait + * for 2s (SECONDS_TO_LINGER). This is useful for mitigating + * certain DoS attacks. + */ + if (apr_table_get(c->notes, "short-lingering-close")) { + timeup = apr_time_now() + apr_time_from_sec(SECONDS_TO_LINGER); + } + else { + timeup = apr_time_now() + apr_time_from_sec(MAX_SECS_TO_LINGER); + } continue; } } while (apr_time_now() < timeup); diff --git a/server/core.c b/server/core.c index ab437197..76aae1a3 100644 --- a/server/core.c +++ b/server/core.c @@ -96,6 +96,9 @@ AP_DECLARE_DATA ap_filter_rec_t *ap_core_input_filter_handle; /* magic pointer for ErrorDocument xxx "default" */ static char errordocument_default; +/* Default ap_document_root_check to default value: true */ +AP_DECLARE_DATA int ap_document_root_check = 1; + static void *create_core_dir_config(apr_pool_t *a, char *dir) { core_dir_config *conf; @@ -1183,13 +1186,19 @@ static const char *set_document_root(cmd_parms *cmd, void *dummy, return err; } + /* When ap_document_root_check is false; skip all the stuff below */ + if (!ap_document_root_check) { + conf->ap_document_root = arg; + return NULL; + } + /* Make it absolute, relative to ServerRoot */ arg = ap_server_root_relative(cmd->pool, arg); if (arg == NULL) { return "DocumentRoot must be a directory"; } - /* TODO: ap_configtestonly && ap_docrootcheck && */ + /* TODO: ap_configtestonly */ if (apr_filepath_merge((char**)&conf->ap_document_root, NULL, arg, APR_FILEPATH_TRUENAME, cmd->pool) != APR_SUCCESS || !ap_is_directory(cmd->pool, arg)) { @@ -1831,13 +1840,6 @@ static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg) return missing_container_arg(cmd); } - if (!arg) { - if (thiscmd->cmd_data) - return "<DirectoryMatch > block must specify a path"; - else - return "<Directory > block must specify a path"; - } - cmd->path = ap_getword_conf(cmd->pool, &arg); cmd->override = OR_ALL|ACCESS_CONF; diff --git a/server/gen_test_char.c b/server/gen_test_char.c index 3835102d..a0b55100 100644 --- a/server/gen_test_char.c +++ b/server/gen_test_char.c @@ -30,7 +30,7 @@ #include "apr_lib.h" #if defined(WIN32) || defined(OS2) -#define WANT_WIN32_OS2 +#define NEED_ENHANCED_ESCAPES #endif #endif @@ -80,7 +80,7 @@ int main(int argc, char *argv[]) printf("\n "); /* escape_shell_cmd */ -#if defined(WANT_WIN32_OS2) +#ifdef NEED_ENHANCED_ESCAPES /* Win32/OS2 have many of the same vulnerable characters * as Unix sh, plus the carriage return and percent char. * The proper escaping of these characters varies from unix diff --git a/server/main.c b/server/main.c index 24a54d3f..b893d281 100644 --- a/server/main.c +++ b/server/main.c @@ -321,14 +321,7 @@ static process_rec *init_process(int *argc, const char * const * *argv) static void usage(process_rec *process) { const char *bin = process->argv[0]; - char pad[MAX_STRING_LEN]; - unsigned i; - - for (i = 0; i < strlen(bin); i++) { - pad[i] = ' '; - } - - pad[i] = '\0'; + int pad_len = strlen(bin); #ifdef SHARED_CORE ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL , @@ -340,28 +333,28 @@ static void usage(process_rec *process) #endif ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-C \"directive\"] [-c \"directive\"]", pad); + " %*s [-C \"directive\"] [-c \"directive\"]", pad_len, " "); #ifdef WIN32 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-w] [-k start|restart|stop|shutdown]", pad); + " %*s [-w] [-k start|restart|stop|shutdown]", pad_len, " "); ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-k install|config|uninstall] [-n service_name]", - pad); + " %*s [-k install|config|uninstall] [-n service_name]", + pad_len, " "); #endif #ifdef AP_MPM_WANT_SIGNAL_SERVER #ifdef AP_MPM_WANT_SET_GRACEFUL_SHUTDOWN ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-k start|restart|graceful|graceful-stop|stop]", - pad); + " %*s [-k start|restart|graceful|graceful-stop|stop]", + pad_len, " "); #else ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-k start|restart|graceful|stop]", - pad); + " %*s [-k start|restart|graceful|stop]", pad_len, " "); #endif /* AP_MPM_WANT_SET_GRACEFUL_SHUTDOWN */ #endif ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, - " %s [-v] [-V] [-h] [-l] [-L] [-t] [-S]", pad); + " %*s [-v] [-V] [-h] [-l] [-L] [-t] [-T] [-S]", + pad_len, " "); ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, "Options:"); @@ -440,6 +433,8 @@ static void usage(process_rec *process) " -M : a synonym for -t -D DUMP_MODULES"); ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, " -t : run syntax check for config files"); + ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, NULL, + " -T : start without DocumentRoot(s) check"); destroy_and_exit_process(process, 1); } @@ -592,6 +587,10 @@ int main(int argc, const char * const argv[]) configtestonly = 1; break; + case 'T': + ap_document_root_check = 0; + break; + case 'S': configtestonly = 1; new = (char **)apr_array_push(ap_server_config_defines); diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 28b60573..f5a72057 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -679,6 +679,11 @@ static void child_main(int child_num_arg) die_now = 1; } } + /* This apr_pool_clear call is redundant, should be redundant, but compensates + * a flaw in the apr reslist code. This should be removed once that flaw has + * been addressed. + */ + apr_pool_clear(ptrans); clean_child_exit(0); } diff --git a/server/mpm_common.c b/server/mpm_common.c index a95b2312..1c50d45b 100644 --- a/server/mpm_common.c +++ b/server/mpm_common.c @@ -965,7 +965,6 @@ int ap_signal_server(int *exit_status, apr_pool_t *pconf) apr_status_t rv; pid_t otherpid; int running = 0; - int have_pid_file = 0; const char *status; *exit_status = 0; @@ -983,7 +982,6 @@ int ap_signal_server(int *exit_status, apr_pool_t *pconf) status = "httpd (no pid file) not running"; } else { - have_pid_file = 1; if (kill(otherpid, 0) == 0) { running = 1; status = apr_psprintf(pconf, @@ -1058,12 +1056,10 @@ void ap_mpm_rewrite_args(process_rec *process) apr_getopt_t *opt; char optbuf[3]; const char *optarg; - int fixed_args; mpm_new_argv = apr_array_make(process->pool, process->argc, sizeof(const char **)); *(const char **)apr_array_push(mpm_new_argv) = process->argv[0]; - fixed_args = mpm_new_argv->nelts; apr_getopt_init(&opt, process->pool, process->argc, process->argv); opt->errfn = NULL; optbuf[0] = '-'; diff --git a/server/request.c b/server/request.c index 0a53529f..1801cf7b 100644 --- a/server/request.c +++ b/server/request.c @@ -351,7 +351,8 @@ static int resolve_symlink(char *d, apr_finfo_t *lfi, int opts, apr_pool_t *p) /* Save the name from the valid bits. */ savename = (lfi->valid & APR_FINFO_NAME) ? lfi->name : NULL; - if (opts & OPT_SYM_LINKS) { + /* if OPT_SYM_OWNER is unset, we only need to check target accessible */ + if (!(opts & OPT_SYM_OWNER)) { if ((res = apr_stat(&fi, d, lfi->valid & ~(APR_FINFO_NAME | APR_FINFO_LINK), p)) != APR_SUCCESS) { @@ -373,7 +374,7 @@ static int resolve_symlink(char *d, apr_finfo_t *lfi, int opts, apr_pool_t *p) * owner of the symlink, then get the info of the target. */ if (!(lfi->valid & APR_FINFO_OWNER)) { - if ((res = apr_stat(&fi, d, + if ((res = apr_stat(lfi, d, lfi->valid | APR_FINFO_LINK | APR_FINFO_OWNER, p)) != APR_SUCCESS) { return HTTP_FORBIDDEN; diff --git a/server/scoreboard.c b/server/scoreboard.c index 060de5ca..85f37557 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -266,14 +266,12 @@ apr_status_t ap_cleanup_scoreboard(void *d) */ int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) { - int running_gen = 0; int i; #if APR_HAS_SHARED_MEMORY apr_status_t rv; #endif if (ap_scoreboard_image) { - running_gen = ap_scoreboard_image->global->running_generation; ap_scoreboard_image->global->restart_time = apr_time_now(); memset(ap_scoreboard_image->parent, 0, sizeof(process_score) * server_limit); @@ -315,7 +313,7 @@ int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) } ap_scoreboard_image->global->sb_type = sb_type; - ap_scoreboard_image->global->running_generation = running_gen; + ap_scoreboard_image->global->running_generation = 0; ap_scoreboard_image->global->restart_time = apr_time_now(); apr_pool_cleanup_register(p, NULL, ap_cleanup_scoreboard, apr_pool_cleanup_null); diff --git a/server/util.c b/server/util.c index e16b8eb2..ac429c78 100644 --- a/server/util.c +++ b/server/util.c @@ -387,7 +387,7 @@ AP_DECLARE(char *) ap_pregsub(apr_pool_t *p, const char *input, if (no > 9) { /* Ordinary character. */ if (c == '\\' && (*src == '$' || *src == '&')) - c = *src++; + src++; len++; } else if (no < nmatch && pmatch[no].rm_so < pmatch[no].rm_eo) { diff --git a/server/vhost.c b/server/vhost.c index 5b79fea5..b8e9ca75 100644 --- a/server/vhost.c +++ b/server/vhost.c @@ -706,25 +706,27 @@ static void fix_hostname(request_rec *r) char *dst; apr_port_t port; apr_status_t rv; + const char *c; /* According to RFC 2616, Host header field CAN be blank. */ if (!*r->hostname) { return; } + /* apr_parse_addr_port will interpret a bare integer as a port + * which is incorrect in this context. So treat it separately. + */ + for (c = r->hostname; apr_isdigit(*c); ++c); + if (!*c) { /* pure integer */ + return; + } + rv = apr_parse_addr_port(&host, &scope_id, &port, r->hostname, r->pool); if (rv != APR_SUCCESS || scope_id) { goto bad; } - if (!host && port) { - /* silly looking host ("Host: 123") but that isn't our job - * here to judge; apr_parse_addr_port() would think we had a port - * but no address - */ - host = apr_itoa(r->pool, (int)port); - } - else if (port) { + if (port) { /* Don't throw the Host: header's port number away: save it in parsed_uri -- ap_get_server_port() needs it! */ /* @@@ XXX there should be a better way to pass the port. |