Skip to content
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

Add an Option to Limit the Sandbox Child Process Memory #192

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

turbo
Copy link

@turbo turbo commented Apr 24, 2017

This change adds an additional parameter --limit-mem VALUE, which when supplied
sets the maximum size of the child process's virtual memory (address space) to
VALUE megabytes. This affects memory mapping and stack expansion calls.

This change adds an additional parameter --limit-mem VALUE, which when supplied
sets the maximum size of the child process's virtual memory (address space) to
VALUE megabytes. This affects memory mapping and stack expansion calls.
@rh-atomic-bot
Copy link

Can one of the admins verify this patch?
I understand the following commands:

  • bot, add author to whitelist
  • bot, test pull request
  • bot, test pull request once

@alexlarsson
Copy link
Collaborator

This needs CAP_SYS_RESOURCE to raise the hard limit, which we do not have, at least in the unprivileged user namespace case. However, it will still work for lowering the limit, which is still interesting.

It does not fully protect against malicious memory use though, as you can have any number of pids with this much memory each.

Of course, you can already get similar functionallitty by using ulimit before you start the bwrap, but that is not as convenient.

@alexlarsson
Copy link
Collaborator

If we do this we probably also need to verify that you're not trying to raise the hard limit in the setuid bwrap case.

@turbo
Copy link
Author

turbo commented Apr 25, 2017

This needs CAP_SYS_RESOURCE to raise the hard limit, which we do not have, at least in the unprivileged user namespace case. However, it will still work for lowering the limit, which is still interesting.

Yes, sorry if this was unclear. The intention is to set a lower soft limit, not to raise any limits.

It does not fully protect against malicious memory use though, as you can have any number of pids with this much memory each.

I use this option exactly for this purpose. E.g. an interactive shell or script compiles and runs untrusted code - in my case these are single-threaded python scripts. The limit does a good enough job of killing the process if it tries to allocate more memory, but keeps the calling shell alive. This should maybe be noted in the parameter description.

If we do this we probably also need to verify that you're not trying to raise the hard limit in the setuid bwrap case.

Good catch. I removed the setuid code in my offline branch, that's why I missed it when modifying my upstream branch.

@@ -2216,6 +2237,13 @@ main (int argc,
prctl (PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &seccomp_prog) != 0)
die_with_error ("prctl(PR_SET_SECCOMP)");

/* Optionally limit memory. This must occur after the fork and
* before the exec* call. */
if (opt_limit_mem) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This needs to come before the seccomp filter - see the rationale in #155

Copy link
Collaborator

Choose a reason for hiding this comment

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

Also, code style is GNU - braces on a new line.

* before the exec* call. */
if (opt_limit_mem) {
limit_mem.rlim_cur = limit_mem.rlim_max = opt_limit_mem * 1048576;
setrlimit(RLIMIT_DATA, &limit_mem);
Copy link
Collaborator

Choose a reason for hiding this comment

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

And yeah, we should probably just disable this in the setuid case...unless it seems easy to get the current limit and check it ourself. (Alternatively, maybe we could temporarily drop CAP_SYS_RESOURCE before doing this call? Actually, maybe we're dropping it already?)

Copy link
Author

Choose a reason for hiding this comment

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

I'd like to go with the safer method first, denying this option in setuid mode. I don't know if there's a way to reliably check the limit for all supported platforms. That seems like something that's less stable and could be done in the future.

Checking the cap is a better way. I'll investigate.

@cgwalters
Copy link
Collaborator

Big picture of course - limits like this are really better done via cgroups. I'm not opposed to carrying some rlimit code though.

Should we also try to add a knob to limit max pids like systemd's LimitNPROC?

@turbo
Copy link
Author

turbo commented Apr 29, 2017

Should we also try to add a knob to limit max pids like systemd's LimitNPROC?

IMO that's a good idea. From my perspective (sandboxing CI tasks), the most important limits are:

  • memory
  • overall size of disk usage (i.e. the maximum amount of data stored in the non-r/o binds and tmpfs mounts)
  • non-loopback network bandwidth and/or network xfer

There are some limits that might be useful for a multi-tenant system, but they are maybe better suited for the orchestration tool that calls bwrap:

  • CPU share
  • Runtime
  • IOPS

et al.

@rh-atomic-bot
Copy link

☔ The latest upstream changes (presumably #196) made this pull request unmergeable. Please resolve the merge conflicts.

@rh-atomic-bot
Copy link

Can one of the admins verify this patch?
I understand the following commands:

  • bot, add author to whitelist
  • bot, test pull request
  • bot, test pull request once

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants