diff --git a/core/utils.c b/core/utils.c index 7eac969b..52142dca 100644 --- a/core/utils.c +++ b/core/utils.c @@ -729,6 +729,14 @@ void uwsgi_as_root() { } usl = usl->next; } + + // we could now patch the binary + if (uwsgi.unprivileged_binary_patch) { + uwsgi.argv[0] = uwsgi.unprivileged_binary_patch; + execvp(uwsgi.unprivileged_binary_patch, uwsgi.argv); + uwsgi_error("execvp()"); + exit(1); + } } else { if (uwsgi.chroot && !uwsgi.is_a_reload) { diff --git a/core/uwsgi.c b/core/uwsgi.c index d54c0d3a..c07c6839 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -318,6 +318,8 @@ static struct uwsgi_option uwsgi_base_options[] = { {"check-interval", required_argument, 0, "set the interval (in seconds) of master checks", uwsgi_opt_set_dyn, (void *) UWSGI_OPTION_MASTER_INTERVAL, 0}, {"forkbomb-delay", required_argument, 0, "sleep for the specified number of seconds when a forkbomb is detected", uwsgi_opt_set_int, &uwsgi.forkbomb_delay, UWSGI_OPT_MASTER}, {"binary-path", required_argument, 0, "force binary path", uwsgi_opt_set_str, &uwsgi.binary_path, 0}, + {"privileged-binary-patch", required_argument, 0, "patch the uwsgi binary with a new command (before privileges drop)", uwsgi_opt_set_str, &uwsgi.privileged_binary_patch, 0}, + {"unprivileged-binary-patch", required_argument, 0, "patch the uwsgi binary with a new command (after privileges drop)", uwsgi_opt_set_str, &uwsgi.unprivileged_binary_patch, 0}, #ifdef UWSGI_ASYNC {"async", required_argument, 0, "enable async mode with specified cores", uwsgi_opt_set_int, &uwsgi.async, 0}, #endif @@ -2010,6 +2012,15 @@ int main(int argc, char *argv[], char *envp[]) { usl = usl->next; } + // we could now patch the binary + if (uwsgi.privileged_binary_patch) { + uwsgi.argv[0] = uwsgi.privileged_binary_patch; + execvp(uwsgi.privileged_binary_patch, uwsgi.argv); + uwsgi_error("execvp()"); + exit(1); + } + + // call jail systems for (i = 0; i < uwsgi.gp_cnt; i++) { diff --git a/uwsgi.h b/uwsgi.h index 6d9b4078..bc787ceb 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -1349,6 +1349,9 @@ struct uwsgi_server { struct uwsgi_string_list *exec_as_user_atexit; struct uwsgi_string_list *exec_pre_app; + char *privileged_binary_patch; + char *unprivileged_binary_patch; + struct uwsgi_logger *loggers; struct uwsgi_logger *choosen_logger; char *requested_logger;