0

I want to run a binary in Python, but I want to disallow the binary from making new processes. It seems like the standard way to do this is to call setrlimit through the resource module, and constrain resource.RLIMIT_NPROC. However, my attempts have all failed.

Here's a simple example:

foo.py:

import subprocess
import resource
import os

def set_nproc() -> None: 
    resource.setrlimit(
        resource.RLIMIT_NPROC,
        (1, 1),
    )

if __name__ == '__main__':
    subprocess.Popen(['./a.out'], preexec_fn=set_nproc)

foo.c:

#include <unistd.h>
#include <stdlib.h>

int main() {
    printf("Running C Program!\n");
    int pid = fork();
    sleep(10);
    return 0;
}

Also, a.out is the binary produced by compiling foo.c. Running foo.py, I'd expect the following to take place:

  1. subprocess.Popen will spawn a new process. Before running ./a.out, it will run the set_nproc function, which will set the RLIMIT_NPROC soft and hard limit to 1.

  2. The new process will run the binary a.out. The binary will print Running C Program! and terminate because the next line tries to spawn a new process, which is not allowed.

It seems like my understanding is not correct because the C program actually terminates to completion (i.e., I do not receive any sort of error). How can I fix this?

Note: I realize that setrlimit imposes a limit on the user and not the process. Even then, I'd expect an error to take place somewhere here.

starball
  • 20,030
  • 7
  • 43
  • 238
Joey
  • 209
  • 2
  • 7
  • Your code worked, though you wouldn't know because you never checked for the assigned `pid` and verified that it isn't the failure value `-1`. Try adding a `printf("this is pid %d\n", pid);` after `fork()`, compile and run it, and then compare with adjustment the rlimit value in the Python code from what you had to a much higher number (greater than the total process that exists for the user running that program for the entire system). [More information](https://stackoverflow.com/questions/44866250/fork-failing-in-c) (this question may be considered a duplicate of that in essence). – metatoaster Jan 05 '23 at 09:05
  • (also you need to `#include ` instead of `stdlib` for `printf`, but this isn't an important detail for the question at hand, but is important if you want the C program to be more correct; the other thing is to use the `pid_t` instead of `int` to capture the `pid` value, and then `%ld` for the token as per [thread](https://stackoverflow.com/questions/20533606/what-is-the-correct-printf-specifier-for-printing-pid-t) to ensure most correctness.) – metatoaster Jan 05 '23 at 09:11
  • Essentially, many things in C's standard library will run and return something and won't crash the program, unless you try to use that return value inappropriately, and then it may crash with a segmentation fault. – metatoaster Jan 05 '23 at 09:15

0 Answers0