php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch fmp_scoreboard_proc_oob_v2.patch for FPM related Bug #81026Patch version 2021-05-31 21:16 UTC Return to Bug #81026 | Download this patchThis patch is obsolete Obsoleted by patches: Patch Revisions:Developer: bukka@php.netFrom 3ebba0ace5d10be0c4364413516bafe697ed42a9 Mon Sep 17 00:00:00 2001 From: Jakub Zelenka <bukka@php.net> Date: Mon, 31 May 2021 14:26:09 +0100 Subject: [PATCH] Fix bug #81026 (PHP-FPM oob R/W in root process leading to privilege escalation) --- sapi/fpm/fpm/fpm_request.c | 6 +++--- sapi/fpm/fpm/fpm_scoreboard.c | 35 +++++++++++++++++++++++++++++++++++ sapi/fpm/fpm/fpm_scoreboard.h | 2 ++ 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/sapi/fpm/fpm/fpm_request.c b/sapi/fpm/fpm/fpm_request.c index 83401f1553..540949b026 100644 --- a/sapi/fpm/fpm/fpm_request.c +++ b/sapi/fpm/fpm/fpm_request.c @@ -227,7 +227,7 @@ void fpm_request_check_timed_out(struct fpm_child_s *child, struct timeval *now, { struct fpm_scoreboard_proc_s proc, *proc_p; - proc_p = fpm_scoreboard_proc_acquire(child->wp->scoreboard, child->scoreboard_i, 1); + proc_p = fpm_scoreboard_proc_acquire_from_child(child, 1); if (!proc_p) { zlog(ZLOG_WARNING, "failed to acquire scoreboard"); return; @@ -287,7 +287,7 @@ int fpm_request_is_idle(struct fpm_child_s *child) /* {{{ */ struct fpm_scoreboard_proc_s *proc; /* no need in atomicity here */ - proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i); + proc = fpm_scoreboard_proc_get_from_child(child); if (!proc) { return 0; } @@ -302,7 +302,7 @@ int fpm_request_last_activity(struct fpm_child_s *child, struct timeval *tv) /* if (!tv) return -1; - proc = fpm_scoreboard_proc_get(child->wp->scoreboard, child->scoreboard_i); + proc = fpm_scoreboard_proc_get_from_child(child); if (!proc) { return -1; } diff --git a/sapi/fpm/fpm/fpm_scoreboard.c b/sapi/fpm/fpm/fpm_scoreboard.c index 328f999f0c..79a7480201 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.c +++ b/sapi/fpm/fpm/fpm_scoreboard.c @@ -6,6 +6,7 @@ #include <time.h> #include "fpm_config.h" +#include "fpm_children.h" #include "fpm_scoreboard.h" #include "fpm_shm.h" #include "fpm_sockets.h" @@ -184,6 +185,23 @@ struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *s } /* }}} */ +struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child) /* {{{*/ +{ + struct fpm_worker_pool_s *wp = child->wp; + struct fpm_scoreboard_proc_s *proc = fpm_scoreboard_proc_get(wp->scoreboard, child->scoreboard_i); + ptrdiff_t proc_start = (uintptr_t) wp->scoreboard + sizeof(struct fpm_scoreboard_s); + ptrdiff_t proc_end = proc_start + (wp->config->pm_max_children - 1) * sizeof(struct fpm_scoreboard_proc_s *); + uintptr_t proc_position = (uintptr_t) proc; + + if (proc_position < proc_start || proc_position > proc_end) { + zlog(ZLOG_WARNING, "failed to get proc from the child scoreboard because the proc pointer is invalid"); + return NULL; + } + + return proc; +} +/* }}} */ + struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang) /* {{{ */ { struct fpm_scoreboard_s *s; @@ -225,6 +243,23 @@ struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_ } /* }}} */ +struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire_from_child(struct fpm_child_s *child, int nohang) /* {{{ */ +{ + struct fpm_scoreboard_proc_s *proc; + + proc = fpm_scoreboard_proc_get_from_child(child); + if (!proc) { + return NULL; + } + + if (!fpm_spinlock(&proc->lock, nohang)) { + return NULL; + } + + return proc; +} +/* }}} */ + void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc) /* {{{ */ { if (!proc) { diff --git a/sapi/fpm/fpm/fpm_scoreboard.h b/sapi/fpm/fpm/fpm_scoreboard.h index 1fecde1d0f..ff7ed1806d 100644 --- a/sapi/fpm/fpm/fpm_scoreboard.h +++ b/sapi/fpm/fpm/fpm_scoreboard.h @@ -72,10 +72,12 @@ int fpm_scoreboard_init_child(struct fpm_worker_pool_s *wp); void fpm_scoreboard_update(int idle, int active, int lq, int lq_len, int requests, int max_children_reached, int slow_rq, int action, struct fpm_scoreboard_s *scoreboard); struct fpm_scoreboard_s *fpm_scoreboard_get(); struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get(struct fpm_scoreboard_s *scoreboard, int child_index); +struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_get_from_child(struct fpm_child_s *child); struct fpm_scoreboard_s *fpm_scoreboard_acquire(struct fpm_scoreboard_s *scoreboard, int nohang); void fpm_scoreboard_release(struct fpm_scoreboard_s *scoreboard); struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire(struct fpm_scoreboard_s *scoreboard, int child_index, int nohang); +struct fpm_scoreboard_proc_s *fpm_scoreboard_proc_acquire_from_child(struct fpm_child_s *child, int nohang); void fpm_scoreboard_proc_release(struct fpm_scoreboard_proc_s *proc); void fpm_scoreboard_free(struct fpm_scoreboard_s *scoreboard); -- 2.25.1 |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Thu Nov 21 14:01:29 2024 UTC |