2014-02-09 32 views
0

是否存在一种编程方式来限制持续时间,内存使用情况并以C/C++或Ruby中Linux程序执行的特权用户身份运行?如何在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 

两个声明使得那个命令运行相同的用户执行人,采用整体处理能力和内存,因为他们喜欢。

回答

1

您将需要使用setrlimit系统调用来限制内存(Process::RLIMIT_AS)。为了限制程序的运行时间,您只能控制进程获得CPU时间的总秒数(以免计入睡眠或等待I/O所用的时间)。这与Process::CPU完成。

Process::Sys.setgid放弃特权,然后Process::Sys.setuid设置这些rlimits后,但在此之前调用你的目标进程与Process::exec

实施例的目标程序:

#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; 
} 

和伴随Ruby脚本调用它(运行该脚本与根,例如sudo /tmp/foo.rb):

#!/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') 

最后,我的机器上运行的输出:

$ 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)系统调用;设置调用进程的有效用户标识。

以下是Ruby的例子(见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或命令行susudo

如果要限制资源,您希望使用shell的setrlimit系统调用或ulimit。这将限制内存使用量等,但不是总运行时间 - 如果需要,您将不得不跟踪流程和kill

您也可以查看nice来设置其优先级。

相关问题