如何用setuid或功能CAP_SYS_RESOURCE以编程方式提高实时优先级的ulimit硬限制?

我想在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)

回答:

setuid root不起作用的事实是线索。

事实证明,上面的测试程序在安装了nosuid的分区中,因此setuid位不起作用。如果您不信任分区中的setuid位,那么您可能也不应该相信文件功能。事实上,事实证明,使用nosuid进行安装时,文件功能也将被忽略。

似乎luks加密的主目录往往被安装nosuid

我离开这个问题,因为有很多搜索引擎命中“linux功能nosuid”,表明这个问题上浪费了很多时间(但当然你不知道要搜索直到你找到它了)。

以上是 如何用setuid或功能CAP_SYS_RESOURCE以编程方式提高实时优先级的ulimit硬限制? 的全部内容, 来源链接: utcz.com/qa/262682.html

回到顶部