2014-02-09 9 views
0

C/C++ 또는 Ruby에서 실행 시간, 메모리 사용을 제한하고 Linux 프로그램 실행의 권한이 적은 사용자로 프로그래밍 방식으로 실행합니까?리눅스에서 프로그램 런타임, 메모리 사용 및 특정 사용자로 프로그래밍 방식으로 제한하는 방법

시스템 또는 "이 작업을 수행 할 수 없습니다.

sprintf(cmd_str,"/tmp/pro-%d </tmp/in.txt> /tmp-%d.txt",id,id); 
system(cmd_str); // in C 

`/tmp/pro-#{id} </tmp/in.txt> /tmp/out-#{id}.txt` // in Ruby 

both 명령문은 해당 명령을 실행 프로그램과 동일한 사용자로 실행하고 전체 처리 능력 및 메모리를 원하는대로 사용합니다.

답변

1

메모리를 제한하기 위해 setrlimit 시스템 콜을 사용하고 싶습니다 (Process::RLIMIT_AS). 프로그램의 런타임을 제한하기 위해, 프로세스가 CPU 시간을 얻는 총 시간 (즉, 잠자기 또는 I/O에서 대기하는 시간을 고려하지 않음) 만 제어 할 수 있습니다. 그게 Process::CPU입니다. Process::Sys.setgid

드롭 권한이이 rlimits을 설정 한 후 Process::Sys.setuid다음,하지만 Process::exec하여 대상 프로세스를 호출하기 전에.

예 대상 프로그램 : 마지막으로 내 컴퓨터에서 실행의 출력을

#!/usr/bin/env ruby 

TARGET_GID = 99 
TARGET_UID = 99 

Process::setrlimit(Process::RLIMIT_AS, 1024 * 1024 * 5) 
Process::setrlimit(Process::RLIMIT_CPU, 3) 

Process::Sys.setgid(TARGET_GID) 
Process::Sys.setuid(TARGET_UID) 

Process::exec('/tmp/test') 

그리고 :

#include <stdio.h> 
#include <stdlib.h> 

#include <unistd.h> 

#define ALLOC_SIZE_1 1024 
#define ALLOC_SIZE_2 (1024 * 1024 * 5) 

int 
main(int argc, char *argv[]) 
{ 
    char *buf; 

    fprintf(stderr, "[+] uid: %d, gid: %d\n", getuid(), getgid()); 

    fprintf(stderr, "[+] trying to allocate %d bytes (should succeed)...\n", ALLOC_SIZE_1); 
    if (NULL == (buf = malloc(ALLOC_SIZE_1))) { 
    fprintf(stderr, "[!] failed!\n"); 
    return -1; 
    } 

    fprintf(stderr, "[+] success.\n"); 
    free(buf); 

    fprintf(stderr, "[+] trying to allocate %d bytes (should fail)...\n", ALLOC_SIZE_2); 
    if (NULL != (buf = malloc(ALLOC_SIZE_2))) { 
    fprintf(stderr, "[!] succeeded! (should have failed.)\n"); 
    return -1; 
    } 

    fprintf(stderr, "[+] ok. now doing infinite loop (should get killed pretty soon)...\n"); 
    for (;;); 

    return 0; 
} 

그리고 그것을 호출하는 루비 스크립트를 동반 (예 sudo /tmp/foo.rb와 루트로이 스크립트를 실행) :

$ sudo ./run.rb 
[+] uid: 99, gid: 99 
[+] trying to allocate 1024 bytes (should succeed)... 
[+] success. 
[+] trying to allocate 5242880 bytes (should fail)... 
[+] ok. now doing infinite loop (should get killed pretty soon)... 
$ 
2

seteuid(2) 시스템 호출 사용; 호출 한 프로세스의 유효 사용자 ID를 설정합니다.

다음

루비 예 ( Process::Sys.seteuid 참조)

Process.uid # => 0 
Process.euid # => 0 
Process::Sys.seteuid(1000) # Etc::getpwnam('falsetru').uid == 1000 
Process.uid # => 0 
Process.euid # => 1000 
1

@falsetru가 언급 한 바와 같이, 시스템이 다른 사용자가 setrlimit 또는 명령 줄 su 또는 sudo에서 같이 실행하려는 전화입니다.

자원을 제한하려면 시스템 호출 setrlimit 또는 ulimit을 사용하고 싶습니다. 메모리 사용량 등은 제한되지만 총 실행 시간은 제한됩니다. 원하는 경우 프로세스를 추적하고 kill 정보를 추적해야합니다.

nice에서 우선 순위를 설정할 수도 있습니다.