diff --git a/README.rst b/README.rst index e916e614..6a6fe362 100644 --- a/README.rst +++ b/README.rst @@ -265,12 +265,25 @@ Limitations * Sandbox isolation is achieved via AppArmor confinement. Codejail facilitates this, but cannot isolate execution without the use of AppArmor. * Resource limits can only be constrained using the mechanisms that Linux's - rlimit makes available. While rlimit can limit the size of any one file that - a process can create, and can limit the number of files it has open at any - one time, it cannot limit the total number of files written, and therefore - cannot limit the total number of bytes written across *all* files. - A partial mitigation is to constrain the max execution time. (All files - written in the sandbox will be deleted at end of execution, in any case.) + rlimit makes available. Some notable deficiencies: + + * While rlimit's ``FSIZE`` can limit the size of any one file that + a process can create, and can limit the number of files it has open at any + one time, it cannot limit the total number of files written, and therefore + cannot limit the total number of bytes written across *all* files. + A partial mitigation is to constrain the max execution time. (All files + written in the sandbox will be deleted at end of execution, in any case.) + * The ``NPROC`` limit constrains the ability of the *current* process to + create new threads and processes, but the usage count (how many processes + already exist) is the sum across *all* processes with the same UID, even in + other containers on the same host where the UID may be mapped to a different + username. This constraint also applies to the app user due to how the + rlimits are applied. Even if a UIDs are chosen so they aren't used by other + software on the host, multiple codejail sandbox processes on the same host + will share this usage pool and can reduce each other's ability to create + processes. In this situation, ``NPROC`` will need to be set higher than it + would be for a single codejail instance taking a single request at a time. + * Sandboxes do not have strong isolation from each other. Under proper configuration, untrusted code should not be able to discover other actively running code executions, but if this assumption is violated then one sandbox diff --git a/codejail/jail_code.py b/codejail/jail_code.py index 792777b9..b00d6164 100644 --- a/codejail/jail_code.py +++ b/codejail/jail_code.py @@ -88,7 +88,8 @@ def is_configured(command): "VMEM": 0, # Size of files creatable, in bytes, defaulting to nothing can be written. "FSIZE": 0, - # The number of processes and threads to allow. + # The number of processes and threads to allow for the sandbox user (total + # across entire host). "NPROC": 15, # Whether to use a proxy process or not. None means use an environment # variable to decide. NOTE: using a proxy process is NOT THREAD-SAFE, only @@ -127,14 +128,17 @@ def set_limit(limit_name, value): * `"FSIZE"`: the maximum size of files creatable by the jailed code, in bytes. The default is 0 (no files may be created). - * `"NPROC"`: the maximum number of process or threads creatable by the - jailed code. The default is 15. + * `"NPROC"`: the maximum number of process or threads allowed for + jailed code across the entire host (combined across all instances + in all containers). This includes processes owned by the same UID + in containers where that UID is mapped to a different username. + The default is 15. * `"PROXY"`: 1 to use a proxy process, 0 to not use one. This isn't really a limit, sorry about that. Limits are process-wide, and will affect all future calls to jail_code. - Providing a limit of 0 will disable that limit. + Providing a limit of 0 will disable that limit, unless otherwise specified. """ LIMITS[limit_name] = value