2016-11-28 107 views
0

我想在linux的SCHED_FIFO實時課下運行一個程序。我寧願將RTPRIO的用戶硬限制設置爲0,並以編程方式提高僅限於單個進程的硬限制。廣泛地聲稱,如果我授予過程CAP_SYS_RESOURCE以允許其提高硬限制,例如,man setrlimit 2如何用setuid或功能CAP_SYS_RESOURCE以編程方式提高實時優先級的ulimit硬限制?

軟限制是內核對相應資源執行的值。硬限制是軟限制的上限:非特權進程只能將其軟限制設置爲從0到硬限制的範圍內的值,並且(不可逆地)降低其硬限制。特權進程(在Linux下:具有CAP_SYS_RESOURCE功能的進程)可能會對限制值進行任意更改。

但是,我似乎無法得到這個爲我工作。下面是測試代碼:

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

這個工作沒有特權預期99的硬性限制:

$ ./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. 
$ 

它的工作原理與使用sudo的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. 
$ 

但setuid root無法正常工作:

$ 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功能nosuid」,表明這個問題上浪費了很多時間(但當然你不知道要搜索直到你找到它了)。

相關問題