Page MenuHomeFreeBSD

Allow subset of wait4(2) functionality in Capsicum mode
Needs ReviewPublic

Authored by trasz on Mar 15 2024, 12:22 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sat, May 11, 4:05 AM
Unknown Object (File)
Fri, May 10, 4:02 AM
Unknown Object (File)
Sat, May 4, 1:22 PM
Unknown Object (File)
Tue, Apr 30, 5:01 AM
Unknown Object (File)
Fri, Apr 26, 4:13 AM
Unknown Object (File)
Sat, Apr 20, 10:56 PM
Unknown Object (File)
Sat, Apr 20, 6:31 AM
Unknown Object (File)
Fri, Apr 19, 7:13 PM

Details

Reviewers
brooks
Group Reviewers
capsicum
Summary

The usual way of handling process exit exit in capsicum(4) mode is by using process
descriptors (pdfork(2)) instead of the traditional fork(2)/wait4(2) API. But most apps
hadn't been converted this way, and many cannot because the wait is hidden behind
a library APIs that revolve around PID numbers and not descriptors; GLib's
g_spawn_check_wait_status(3) is one example.

Thus, provide backwards compatibility by allowing the wait(2) family of functions
in Capsicum mode, except for child processes created by pdfork(2).

One practical result is that with this patch, a capsicated irssi(1) is no longer
leaving zombies around.

Sponsored by: Innovate UK

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 57703
Build 54591: arc lint + arc unit

Event Timeline

I think this behavior should be documented in the man pages (capsicum/wait), as it isn't obvious.

Also, do you have any particular cases or example of application where you want to use it?

What about wait6?

Should there be a way for a program to disable this?

I agree this should be documented somewhere, but at the moment wait(2) doesn't mention Capsicum at all, and capsicum(4) doesn't mention wait(2). Perhaps a paragraph in pdfork(2), something along the lines of "processes created with pdfork cannot be waited for by a parent running in capsicum(4) mode"?

Regarding use case - sh(1) when running with D44373 in place. Also either bmake(1) or clang(1) in a similar circumstances.

As for wait6(2) - definitely; I'll update the patch. Should I also handle wait(2) similarly, or is that just for backward compatibility?

As for disabling - I'm not sure. Are there cases where we'd need to?

Fix panic which occured when the PID is specified explictly.
Also handle wait6(2). Add some documentation. Pacify a test.

lib/libsys/wait.2
606–614

I found the edit hard to read, particularly the second sentence. Perhaps this option is better.

trasz edited the summary of this revision. (Show Details)

Man page fix from Brooks.

Hey folks,

Sorry to Statler / Waldorf, but I have a student who's been bumping up against wait4 limitations when doing some transparent/oblivious sandboxing stuff, so perhaps this is timely feedback! :)

If we're going to allow wait4 and/or wait6, I'm wondering if it would make sense to maintain the disallowance of access to the (global) PID and process group ID namespaces. Allowing "wait for any of my children" would help with a lot of processes, whereas opening up any global namespace access seems to weaken the model in ways that I don't (yet) understand...

Jon

sys/kern/kern_exit.c
1209

If IN_CAPABILITY_MODE, would it make sense to check and confirm that pid == WAIT_ANY (to avoid using global PID namespace)?

1340

Would it also make sense to check that idtype is P_ALL? That way, the process isn't using the PID or process group ID namespaces...

Sorry to Statler / Waldorf

Hah!

If we're going to allow wait4 and/or wait6, I'm wondering if it would make sense to maintain the disallowance of access to the (global) PID and process group ID namespaces. Allowing "wait for any of my children" would help with a lot of processes, whereas opening up any global namespace access seems to weaken the model in ways that I don't (yet) understand...

Yes - I was uneasy with this proposal (this review) but am happy with it, with your suggestion included. Disallowing unless P_ALL, or with id == 0 P_PID or P_PGID makes sense to me.