Skip to content

New functions/API for secure launching of external programs#1915

Open
Explorer09 wants to merge 6 commits intohtop-dev:mainfrom
Explorer09:program-launcher
Open

New functions/API for secure launching of external programs#1915
Explorer09 wants to merge 6 commits intohtop-dev:mainfrom
Explorer09:program-launcher

Conversation

@Explorer09
Copy link
Copy Markdown
Contributor

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:

  1. Drop set-UID (SUID) privileges before launching a external program (for a forked child process).
  2. Check permission (mode) bits of a program, and the owner and group IDs of the program before launching. It's stricter than what the OS would permit launching. In particular the "other execute" (o+x) bit is now respected only of the program is owned by root. (The u+x and g+x behaviors remain the same, but the code now checks for UID and GID explicitly so that root user won't bypass it.)
  3. Use fexecve(3) to launch program whenever it's available. This avoids a TOCTTOU. (Unfortunately macOS and OpenBSD don't have fexecve yet so I have to keep the vulnerable fallback code.)
  4. When locating a program through the PATH environment 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() and fexecve() calls to use posix_spawn() because posix_spawn() can't achieve the security I want (I need posix_fspawn() instead, but no libc had implemented such interface for me).

@BenBE BenBE added needs-discussion 🤔 Changes need to be discussed and require consent feature request Completely new feature requested labels Feb 23, 2026
@Explorer09 Explorer09 force-pushed the program-launcher branch 2 times, most recently from d918d6d to 36a2a7c Compare March 22, 2026 12:42
@Explorer09 Explorer09 marked this pull request as ready for review March 22, 2026 12:42
@Explorer09 Explorer09 force-pushed the program-launcher branch 3 times, most recently from 027d0c7 to b9ddd81 Compare April 7, 2026 16:12
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature request Completely new feature requested needs-discussion 🤔 Changes need to be discussed and require consent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Security check of external programs before launching

2 participants