From afc1dbd7541dce4cbbe74fe0d94af94e932547b5 Mon Sep 17 00:00:00 2001 From: Packit Date: Oct 26 2020 15:22:32 +0000 Subject: Apply patch httpd-2.4.37-CVE-2019-0211.patch patch_name: httpd-2.4.37-CVE-2019-0211.patch present_in_specfile: true --- diff --git a/include/scoreboard.h b/include/scoreboard.h index 9376da2..92d198d 100644 --- a/include/scoreboard.h +++ b/include/scoreboard.h @@ -148,7 +148,9 @@ struct process_score { apr_uint32_t lingering_close; /* async connections in lingering close */ apr_uint32_t keep_alive; /* async connections in keep alive */ apr_uint32_t suspended; /* connections suspended by some module */ - int bucket; /* Listener bucket used by this child */ + int bucket; /* Listener bucket used by this child; this field is DEPRECATED + * and no longer updated by the MPMs (i.e. always zero). + */ }; /* Scoreboard is now in 'local' memory, since it isn't updated once created, diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index ffe8a23..048ae61 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -2695,7 +2695,6 @@ static int make_child(server_rec * s, int slot, int bucket) ap_scoreboard_image->parent[slot].quiescing = 0; ap_scoreboard_image->parent[slot].not_accepting = 0; - ap_scoreboard_image->parent[slot].bucket = bucket; event_note_child_started(slot, pid); active_daemons++; retained->total_daemons++; @@ -2734,6 +2733,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) * that threads_per_child is always > 0 */ int status = SERVER_DEAD; int child_threads_active = 0; + int bucket = i % num_buckets; if (i >= retained->max_daemons_limit && free_length == retained->idle_spawn_rate[child_bucket]) { @@ -2757,7 +2757,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) */ if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting && ps->generation == retained->mpm->my_generation - && ps->bucket == child_bucket) + && bucket == child_bucket) { ++idle_thread_count; } @@ -2768,7 +2768,9 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) last_non_dead = i; } active_thread_count += child_threads_active; - if (!ps->pid && free_length < retained->idle_spawn_rate[child_bucket]) + if (!ps->pid + && bucket == child_bucket + && free_length < retained->idle_spawn_rate[child_bucket]) free_slots[free_length++] = i; else if (child_threads_active == threads_per_child) had_healthy_child = 1; @@ -2951,13 +2953,14 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets) retained->total_daemons--; if (processed_status == APEXIT_CHILDSICK) { /* resource shortage, minimize the fork rate */ - retained->idle_spawn_rate[ps->bucket] = 1; + retained->idle_spawn_rate[child_slot % num_buckets] = 1; } else if (remaining_children_to_start) { /* we're still doing a 1-for-1 replacement of dead * children with new children */ - make_child(ap_server_conf, child_slot, ps->bucket); + make_child(ap_server_conf, child_slot, + child_slot % num_buckets); --remaining_children_to_start; } } diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 8efda72..7c00625 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -637,8 +637,9 @@ static void child_main(int child_num_arg, int child_bucket) } -static int make_child(server_rec *s, int slot, int bucket) +static int make_child(server_rec *s, int slot) { + int bucket = slot % retained->mpm->num_buckets; int pid; if (slot + 1 > retained->max_daemons_limit) { @@ -716,7 +717,6 @@ static int make_child(server_rec *s, int slot, int bucket) child_main(slot, bucket); } - ap_scoreboard_image->parent[slot].bucket = bucket; prefork_note_child_started(slot, pid); return 0; @@ -732,7 +732,7 @@ static void startup_children(int number_to_start) if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) { continue; } - if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) { + if (make_child(ap_server_conf, i) < 0) { break; } --number_to_start; @@ -741,8 +741,6 @@ static void startup_children(int number_to_start) static void perform_idle_server_maintenance(apr_pool_t *p) { - static int bucket_make_child_record = -1; - static int bucket_kill_child_record = -1; int i; int idle_count; worker_score *ws; @@ -789,6 +787,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p) } retained->max_daemons_limit = last_non_dead + 1; if (idle_count > ap_daemons_max_free) { + static int bucket_kill_child_record = -1; /* kill off one child... we use the pod because that'll cause it to * shut down gracefully, in case it happened to pick up a request * while we were counting @@ -819,10 +818,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p) idle_count, total_non_dead); } for (i = 0; i < free_length; ++i) { - bucket_make_child_record++; - bucket_make_child_record %= retained->mpm->num_buckets; - make_child(ap_server_conf, free_slots[i], - bucket_make_child_record); + make_child(ap_server_conf, free_slots[i]); } /* the next time around we want to spawn twice as many if this * wasn't good enough, but not if we've just done a graceful @@ -867,7 +863,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) if (one_process) { AP_MONCONTROL(1); - make_child(ap_server_conf, 0, 0); + make_child(ap_server_conf, 0); /* NOTREACHED */ ap_assert(0); return !OK; @@ -976,8 +972,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) /* we're still doing a 1-for-1 replacement of dead * children with new children */ - make_child(ap_server_conf, child_slot, - ap_get_scoreboard_process(child_slot)->bucket); + make_child(ap_server_conf, child_slot); --remaining_children_to_start; } #if APR_HAS_OTHER_CHILD diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index 8012fe2..a927942 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -1339,7 +1339,6 @@ static int make_child(server_rec *s, int slot, int bucket) worker_note_child_lost_slot(slot, pid); } ap_scoreboard_image->parent[slot].quiescing = 0; - ap_scoreboard_image->parent[slot].bucket = bucket; worker_note_child_started(slot, pid); return 0; } @@ -1388,6 +1387,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) int any_dead_threads = 0; int all_dead_threads = 1; int child_threads_active = 0; + int bucket = i % num_buckets; if (i >= retained->max_daemons_limit && totally_free_length == retained->idle_spawn_rate[child_bucket]) { @@ -1420,7 +1420,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) if (status <= SERVER_READY && !ps->quiescing && ps->generation == retained->mpm->my_generation && - ps->bucket == child_bucket) { + bucket == child_bucket) { ++idle_thread_count; } if (status >= SERVER_READY && status < SERVER_GRACEFUL) { @@ -1430,6 +1430,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) } active_thread_count += child_threads_active; if (any_dead_threads + && bucket == child_bucket && totally_free_length < retained->idle_spawn_rate[child_bucket] && free_length < MAX_SPAWN_RATE / num_buckets && (!ps->pid /* no process in the slot */ @@ -1615,14 +1616,15 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets) ps->quiescing = 0; if (processed_status == APEXIT_CHILDSICK) { /* resource shortage, minimize the fork rate */ - retained->idle_spawn_rate[ps->bucket] = 1; + retained->idle_spawn_rate[child_slot % num_buckets] = 1; } else if (remaining_children_to_start && child_slot < ap_daemons_limit) { /* we're still doing a 1-for-1 replacement of dead * children with new children */ - make_child(ap_server_conf, child_slot, ps->bucket); + make_child(ap_server_conf, child_slot, + child_slot % num_buckets); --remaining_children_to_start; } }