Skip to content

Implement support for NOEXEC (take 2) #1124

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

bjorn3
Copy link
Collaborator

@bjorn3 bjorn3 commented May 9, 2025

This is using seccomp syscall filtering of the execve and execveat syscalls. Unlike the original sudo this does not depend on using LD_PRELOAD. Instead SECCOMP_RET_USER_NOTIF is used combined with a thread which allows the first exec (as done by sudo itself) and denies all further execs. This makes it robust against both statically linked executables and executables compiled for a different libc than sudo-rs itself. Sudo-rs just like original sudo does not protect against malicious programs with NOEXEC. It doesn't prevent mapping memory as executable, nor does it protect against future syscalls that do an exec like the planned io_uring exec opcode 1. And it also doesn't protect against honest programs that intentionally or not allow the user to write to /proc/self/mem for the same reasons as that it doesn't protect against malicious programs.

Fixes #1071
Fixes #1072


This is a revival of #1073. It now spawns the handler thread after doing a fork.

Footnotes

  1. https://lwn.net/Articles/1002371/

@bjorn3 bjorn3 changed the title Implement support for NOEXEC (try 2) Implement support for NOEXEC (take 2) May 9, 2025
@bjorn3 bjorn3 requested a review from squell May 9, 2025 12:55
@squell squell added C-exec Execution component (interfacing with OS) ubuntu labels May 9, 2025
@squell squell added this to the NOEXEC milestone May 9, 2025
};

if let Some(spawner) = spawn_noexec_handler {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I investigated a bit whether this caused a race condition; but that is not the case since the seccomp filter has already been applied even if the thread hasn't spawned yet. And even if a child process hits the seccomp filter before the thread is ready, it will at that point simply block until the thread has come online, can you confirm that? (E.g. by resolving this comment)

For the pty case there is no potential for a race because of the "green light" mechanism, so this was the only place where I put some extra attention during review.

I do think moving it in the event loop in the future still might be a good idea, but for now using a thread makes for easier maintainability, and we simply don't have the time to fine tine this further. I'll park it as an issue.

@squell
Copy link
Member

squell commented May 12, 2025

Note: I've merged the changes from close_range into this branch locally, so once you have brought it up to date by rebasing or merging I can quickly re-review if we agree on how the merge conflicts should have been resolved (but I'd prefer you do it so we also have two pairs of eyes on that)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-exec Execution component (interfacing with OS) ubuntu
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add NOEXEC support to exec Investigate NOEXEC loading
2 participants