2016-11-28 2 views
0

리눅스 SCHED_FIFO 실시간 클래스 아래에서 프로그램을 실행하고 싶습니다. RTPRIO에 대한 사용자의 하드 제한을 0으로 유지하고 단일 프로세스에 대해 하드 제한을 프로그래밍 방식으로 높이는 것을 선호합니다. 만약 내가 프로세스에 CAP_SYS_RESOURCE을 부여하면 하드 한도를 높일 수 있다고 주장한다. , man setrlimit 2 :setuid 또는 capability CAP_SYS_RESOURCE를 사용하여 프로그래밍 방식으로 실시간 우선 순위에 대한 ulimit 하드 제한을 늘리는 방법은 무엇입니까?

소프트 제한은 커널이 해당 자원에 적용하는 값입니다. 하드 제한은 소프트 제한에 대한 한도로 작용합니다. 권한이없는 프로세스는 소프트 제한을 0에서 하드 제한까지의 값으로 설정하고 하드 제한을 (되돌릴 수 없게) 낮출 수 있습니다. 권한이 부여 된 프로세스 (Linux에서는 CAP_SYS_RESOURCE 권한을 가진 프로세스)가 제한 값을 임의로 변경할 수 있습니다.

그러나 나는 나를 위해이 기능을 사용할 수 없습니다. 다음은 테스트 코드입니다 :

(99)의 하드 제한과 특별한 권한이없이 예상대로이 작동
#include <stdio.h> 
#include <sched.h> 
#include <errno.h> 
#include <string.h> 
#include <sys/resource.h> 

#define PRIORITY (50) 

int main(int argc, char **argv) { 
    struct sched_param param; 
    struct rlimit rl; 
    int e, min_fifo, max_fifo; 

    min_fifo = sched_get_priority_min(SCHED_FIFO); 
    max_fifo = sched_get_priority_max(SCHED_FIFO); 
    printf("For policy SCHED_FIFO min priority is %d, max is %d.\n", 
     min_fifo, max_fifo); 
    if ((min_fifo>PRIORITY)||(max_fifo<PRIORITY)) { 
    printf("Desired priority of %d is out of range.\n", PRIORITY); 
    return 1; 
    } 

    if (getrlimit(RLIMIT_RTPRIO, &rl) != 0) { 
    e = errno; 
    printf("Failed to getrlimit(): %s.\n", strerror(e)); 
    return 1; 
    } 
    printf("RTPRIO soft limit is %d, hard is %d.\n", 
     (int) rl.rlim_cur, (int) rl.rlim_max); 

    // Adjust hard limit if necessary 

    if (rl.rlim_max < PRIORITY) { 
    rl.rlim_max = PRIORITY; 
    if (setrlimit(RLIMIT_RTPRIO, &rl) != 0) { 
     e = errno; 
     printf("Failed to raise hard limit for RTPRIO to %d: %s.\n", 
      (int) rl.rlim_max, strerror(e)); 
     return 1; 
    } 
    printf("Raised hard limit for RTPRIO to %d.\n", (int) rl.rlim_max); 
    } 

    // Adjust soft limit if necessary 

    if (rl.rlim_cur < PRIORITY) { 
    rl.rlim_cur = PRIORITY; 
    if (setrlimit(RLIMIT_RTPRIO, &rl) != 0) { 
     e = errno; 
     printf("Failed to raise soft limit for RTPRIO to %d: %s.\n", 
      (int) rl.rlim_cur, strerror(e)); 
     return 1; 
    } 
    printf("Raised soft limit for RTPRIO to %d.\n", (int) rl.rlim_cur); 
    } 

    // Set desired priority with class SCHED_FIFO 

    param.sched_priority = PRIORITY; 
    if (sched_setscheduler(0, SCHED_FIFO, &param) != 0) { 
    e = errno; 
    printf("Setting policy failed: %s.\n", strerror(e)); 
    return 1; 
    } else { 
    printf("Set policy SCHED_FIFO, priority %d.\n", param.sched_priority); 
    } 

    return 0; 
} 

:

$ sudo ./rtprio 
For policy SCHED_FIFO min priority is 1, max is 99. 
RTPRIO soft limit is 0, hard is 0. 
Raised hard limit for RTPRIO to 50. 
Raised soft limit for RTPRIO to 50. 
Set policy SCHED_FIFO, priority 50. 
$ 
: 0의 하드 제한은 sudo를을 사용하여 예상대로 작동

$ ./rtprio 
For policy SCHED_FIFO min priority is 1, max is 99. 
RTPRIO soft limit is 0, hard is 99. 
Raised soft limit for RTPRIO to 50. 
Set policy SCHED_FIFO, priority 50. 
$ 

그러나 setuid 루트 때 예상대로 작동하지 않습니다.

$ sudo chown root ./rtprio 
$ sudo chgrp root ./rtprio 
$ sudo chmod ug+s ./rtprio 
$ ls -l ./rtprio 
-rwsrwsr-x 1 root root 8948 11月 28 12:04 ./rtprio 
$ ./rtprio 
For policy SCHED_FIFO min priority is 1, max is 99. 
RTPRIO soft limit is 0, hard is 0. 
Failed to raise hard limit for RTPRIO to 50: Operation not permitted. 

는 또한 예기치 않게 모든 기능뿐만 아니라 성능 CAP_SYS_RESOURCE 실패 : 여기 무엇을 놓치고

$ sudo setcap cap_sys_resource=eip ./rtprio 
$ getcap ./rtprio 
./rtprio = cap_sys_resource+eip 
$ ./rtprio 
For policy SCHED_FIFO min priority is 1, max is 99. 
RTPRIO soft limit is 0, hard is 0. 
Failed to raise hard limit for RTPRIO to 50: Operation not permitted. 

$ sudo setcap all=eip ./rtprio 
$ getcap ./rtprio 
./rtprio =eip 
$ ./rtprio 
For policy SCHED_FIFO min priority is 1, max is 99. 
RTPRIO soft limit is 0, hard is 0. 
Failed to raise hard limit for RTPRIO to 50: Operation not permitted. 

?

$ uname -srv 
Linux 3.13.0-100-generiC#147-Ubuntu SMP Tue Oct 18 16:48:51 UTC 2016 
$ lsb_release -a 
No LSB modules are available. 
Distributor ID: Ubuntu 
Description: Ubuntu 14.04.5 LTS 
Release: 14.04 
Codename: trusty 
$ bash --version | head -1 
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu) 

답변

0

사실 setuid root이 작동하지 않는다는 사실이 단서입니다.

위의 테스트 프로그램은 nosuid으로 마운트 된 파티션에 있었기 때문에 setuid 비트는 아무 효과가 없습니다. 파티션의 setuid 비트를 신뢰하지 않으면 파일 기능을 신뢰하지 않아야합니다. 실제로, nosuid으로 마운트 할 때 파일 기능도 무시됩니다.

luks 암호화 된 홈 디렉토리는 nosuid으로 마운트되는 경향이 있습니다.

이 문제에 많은 시간이 낭비되었다는 것을 나타내는 "linux capabilities nosuid"에 대한 검색 엔진 조회수가 많기 때문에이 질문을 떠날 것입니다. (물론 당신은 이것은 당신이 그것을 알아낼 때까지).

관련 문제