New functions/API for secure launching of external programs#1915
Open
Explorer09 wants to merge 6 commits intohtop-dev:mainfrom
Open
New functions/API for secure launching of external programs#1915Explorer09 wants to merge 6 commits intohtop-dev:mainfrom
Explorer09 wants to merge 6 commits intohtop-dev:mainfrom
Conversation
This was referenced Feb 25, 2026
f13b24b to
7d3eac6
Compare
7d3eac6 to
380d1bc
Compare
d918d6d to
36a2a7c
Compare
027d0c7 to
b9ddd81
Compare
This module introduces function interfaces for checking permissions of external programs and launching them with dropped privileges whenever it is appliable. These functions are intended to replace the naive execlp(3) and execvp(3) calls as the latter can launch potentially malicious programs without checking, when given root privileges. This module contains these APIs: * ProgramLauncher_setPath() * ProgramLauncher_execve() Features: * It can drop set-UID (SUID) privileges before launching a program. * It checks the owner ID, group ID, and the permission (mode) bits of the program. The policy of executing is stricter than what the OS would permit execution. In particular it respects the "other execute" (o+x) bit only if the program is owned by the root user. * It uses fexecve(3) rather than execve(2) whenever it is supported by the OS. fexecve() is safe against data race. (Unfortunately macOS and OpenBSD don't yet support fexecve() at the time of writing.) * It can search the program through PATH variable and cache the result. It caches the inode as well as the full program path. If the program executable is quietly swapped during htop runtime, htop will refuse to launch the program until the htop instance ends. Signed-off-by: Kang-Che Sung <explorer09@gmil.com>
b9ddd81 to
6479900
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This feature branch implements an interface for checking an external program's permission and launching a program with dropped privileges when it's applicable.
I wrote this as a sepeate module, tentatively named ProgramLauncher (and I welcome suggestions for better names). It has these features:
o+x) bit is now respected only of the program is owned by root. (Theu+xandg+xbehaviors remain the same, but the code now checks for UID and GID explicitly so that root user won't bypass it.)PATHenvironment variable, the "ProgramLauncher" API can cache the result - keeping the full program path and the inode in the filesystem. If someone quietly swaps the program while an htop instance is running, that htop instance will stop trusting or running the external program (until htop restarts).Included in the branch are changes to lsof (OpenFileScreen), strace/truss (TraceScreen), systemctl (SystemdMeter) and rc-status (OpenRCMeter) to all launch using the new framework. These are examples of how the new module/APIs may be called.
Resolves #1844.
Note that this conflicts with #1893. I have no plans to change the
fork()andfexecve()calls to useposix_spawn()becauseposix_spawn()can't achieve the security I want (I needposix_fspawn()instead, but no libc had implemented such interface for me).