On Fri, Feb 11, 2022 at 02:32:47PM -0600, Eric W. Biederman wrote:
Solar Designer solar@openwall.com writes:
https://lore.kernel.org/all/20210913100140.bxqlg47pushoqa3r@wittgenstein/
Christian was going to revert 2863643fb8b9, but apparently that never happened. Back then, I also suggested:
"Alternatively, we could postpone the set_user() calls until we're running with the new user's capabilities, but that's an invasive change that's likely to create its own issues."
Back then you mentioned that apache suexec was broken. Do you have any more details?
I would like to make certain the apache suexec issue is fixed but without a few details I can't do that. I tried looking but I can't find an public report about apache suexec being broken.
I'm not aware of anyone actually running into this issue and reporting it. The systems that I personally know use suexec along with rlimits still run older/distro kernels, so would not yet be affected.
So my mention was based on my understanding of how suexec works, and code review. Specifically, Apache httpd has the setting RLimitNPROC, which makes it set RLIMIT_NPROC:
https://httpd.apache.org/docs/2.4/mod/core.html#rlimitnproc
The above documentation for it includes:
"This applies to processes forked from Apache httpd children servicing requests, not the Apache httpd children themselves. This includes CGI scripts and SSI exec commands, but not any processes forked from the Apache httpd parent, such as piped logs."
In code, there are:
./modules/generators/mod_cgid.c: ( (cgid_req.limits.limit_nproc_set) && ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, ./modules/generators/mod_cgi.c: ((rc = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, ./modules/filters/mod_ext_filter.c: rv = apr_procattr_limit_set(procattr, APR_LIMIT_NPROC, conf->limit_nproc);
For example, in mod_cgi.c this is in run_cgi_child().
I think this means an httpd child sets RLIMIT_NPROC shortly before it execs suexec, which is a SUID root program. suexec then switches to the target user and execs the CGI script.
Before 2863643fb8b9, the setuid() in suexec would set the flag, and the target user's process count would be checked against RLIMIT_NPROC on execve(). After 2863643fb8b9, the setuid() in suexec wouldn't set the flag because setuid() is (naturally) called when the process is still running as root (thus, has those limits bypass capabilities), and accordingly execve() would not check the target user's process count against RLIMIT_NPROC.
My goal is to come up with a very careful and conservative set of patches that fix all of the known issues with RLIMIT_NPROC.
The most conservative fix for this one would be to revert 2863643fb8b9 (preserving other changes that were made on top of it). I think this commit did not fix a real issue - it attempted to fix what someone thought was a discrepancy, but actually made it worse.
However, your recent patch trying to fix that commit looks like it'd also repair the behavior for suexec.
Thanks,
Alexander