From 7a03be035e7926e8750817b39a4a79d590f2a24e Mon Sep 17 00:00:00 2001 From: Lvwenxuan <1666510747@qq.com> Date: Tue, 31 Dec 2024 18:25:42 +0800 Subject: [PATCH] =?UTF-8?q?/*=20=20*=20Copyright=20(c)=202013-2019=20Huawe?= =?UTF-8?q?i=20Technologies=20Co.,=20Ltd.=20All=20rights=20reserved.=20=20?= =?UTF-8?q?*=20Copyright=20(c)=202020-2021=20Huawei=20Device=20Co.,=20Ltd.?= =?UTF-8?q?=20All=20rights=20reserved.=20=20*=20=20*=20Redistribution=20an?= =?UTF-8?q?d=20use=20in=20source=20and=20binary=20forms,=20with=20or=20wit?= =?UTF-8?q?hout=20modification,=20=20*=20are=20permitted=20provided=20that?= =?UTF-8?q?=20the=20following=20conditions=20are=20met:=20=20*=20=20*=201.?= =?UTF-8?q?=20Redistributions=20of=20source=20code=20must=20retain=20the?= =?UTF-8?q?=20above=20copyright=20notice,=20this=20list=20of=20=20*=20=20?= =?UTF-8?q?=20=20conditions=20and=20the=20following=20disclaimer.=20=20*?= =?UTF-8?q?=20=20*=202.=20Redistributions=20in=20binary=20form=20must=20re?= =?UTF-8?q?produce=20the=20above=20copyright=20notice,=20this=20list=20=20?= =?UTF-8?q?*=20=20=20=20of=20conditions=20and=20the=20following=20disclaim?= =?UTF-8?q?er=20in=20the=20documentation=20and/or=20other=20materials=20?= =?UTF-8?q?=20*=20=20=20=20provided=20with=20the=20distribution.=20=20*=20?= =?UTF-8?q?=20*=203.=20Neither=20the=20name=20of=20the=20copyright=20holde?= =?UTF-8?q?r=20nor=20the=20names=20of=20its=20contributors=20may=20be=20us?= =?UTF-8?q?ed=20=20*=20=20=20=20to=20endorse=20or=20promote=20products=20d?= =?UTF-8?q?erived=20from=20this=20software=20without=20specific=20prior=20?= =?UTF-8?q?written=20=20*=20=20=20=20permission.=20=20*=20=20*=20THIS=20SO?= =?UTF-8?q?FTWARE=20IS=20PROVIDED=20BY=20THE=20COPYRIGHT=20HOLDERS=20AND?= =?UTF-8?q?=20CONTRIBUTORS=20=20*=20"AS=20IS"=20AND=20ANY=20EXPRESS=20OR?= =?UTF-8?q?=20IMPLIED=20WARRANTIES,=20INCLUDING,=20BUT=20NOT=20LIMITED=20T?= =?UTF-8?q?O,=20=20*=20THE=20IMPLIED=20WARRANTIES=20OF=20MERCHANTABILITY?= =?UTF-8?q?=20AND=20FITNESS=20FOR=20A=20PARTICULAR=20=20*=20PURPOSE=20ARE?= =?UTF-8?q?=20DISCLAIMED.=20IN=20NO=20EVENT=20SHALL=20THE=20COPYRIGHT=20HO?= =?UTF-8?q?LDER=20OR=20=20*=20CONTRIBUTORS=20BE=20LIABLE=20FOR=20ANY=20DIR?= =?UTF-8?q?ECT,=20INDIRECT,=20INCIDENTAL,=20SPECIAL,=20=20*=20EXEMPLARY,?= =?UTF-8?q?=20OR=20CONSEQUENTIAL=20DAMAGES=20(INCLUDING,=20BUT=20NOT=20LIM?= =?UTF-8?q?ITED=20TO,=20=20*=20PROCUREMENT=20OF=20SUBSTITUTE=20GOODS=20OR?= =?UTF-8?q?=20SERVICES;=20LOSS=20OF=20USE,=20DATA,=20OR=20PROFITS;=20=20*?= =?UTF-8?q?=20OR=20BUSINESS=20INTERRUPTION)=20HOWEVER=20CAUSED=20AND=20ON?= =?UTF-8?q?=20ANY=20THEORY=20OF=20LIABILITY,=20=20*=20WHETHER=20IN=20CONTR?= =?UTF-8?q?ACT,=20STRICT=20LIABILITY,=20OR=20TORT=20(INCLUDING=20NEGLIGENC?= =?UTF-8?q?E=20OR=20=20*=20OTHERWISE)=20ARISING=20IN=20ANY=20WAY=20OUT=20O?= =?UTF-8?q?F=20THE=20USE=20OF=20THIS=20SOFTWARE,=20EVEN=20IF=20=20*=20ADVI?= =?UTF-8?q?SED=20OF=20THE=20POSSIBILITY=20OF=20SUCH=20DAMAGE.=20=20*/=20#i?= =?UTF-8?q?nclude=20"pthread.h"=20//=20=E5=BC=95=E5=85=A5POSIX=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E5=BA=93=EF=BC=8C=E7=94=A8=E4=BA=8E=E5=A4=9A=E7=BA=BF?= =?UTF-8?q?=E7=A8=8B=E7=BC=96=E7=A8=8B=20#include=20"linux/capability.h"?= =?UTF-8?q?=20//=20=E5=BC=95=E5=85=A5Linux=E8=83=BD=E5=8A=9B=EF=BC=88capab?= =?UTF-8?q?ilities=EF=BC=89=E5=AE=9A=E4=B9=89=EF=BC=8C=E7=94=A8=E4=BA=8E?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=8E=A7=E5=88=B6=20#include=20=20//=20=E5=BC=95=E5=85=A5=E7=B3=BB=E7=BB=9F=E8=83=BD?= =?UTF-8?q?=E5=8A=9B=E6=8E=A5=E5=8F=A3=20#include=20"it=5Ftest=5Fcapabilit?= =?UTF-8?q?y.h"=20//=20=E5=81=87=E8=AE=BE=E6=98=AF=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E6=A1=86=E6=9E=B6=E6=88=96=E6=B5=8B=E8=AF=95=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E7=9A=84=E5=A4=B4=E6=96=87=E4=BB=B6=20#include=20=20?= =?UTF-8?q?//=20=E5=BC=95=E5=85=A5=E4=BF=A1=E5=8F=B7=E5=A4=84=E7=90=86?= =?UTF-8?q?=E5=87=BD=E6=95=B0=20#include=20=20//=20=E5=BC=95?= =?UTF-8?q?=E5=85=A5=E5=9F=BA=E6=9C=AC=E6=95=B0=E6=8D=AE=E7=B1=BB=E5=9E=8B?= =?UTF-8?q?=20#include=20=20//=20=E5=BC=95=E5=85=A5=E6=97=B6?= =?UTF-8?q?=E9=97=B4=E5=A4=84=E7=90=86=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit #define CAP_NUM 2 // 定义能力数组的大小 #define INVAILD_PID 65535 // 定义一个无效的进程ID #define CHANGE_CHILD_UID 1000 // 定义子进程要更改的用户ID // 信号处理函数,当前为空实现 static void Sigac(int param) { return; } // 子进程函数 static void Child() { int i = 10; // 循环计数器 signal(25, Sigac); // 设置信号25的处理函数为Sigac while (i--) { // 循环10次,每次睡眠1秒 sleep(1); } // 睡眠10秒后退出 exit(0); } // 测试子进程的函数 static int TestChild(VOID) { struct __user_cap_header_struct capheader; // 定义能力头部结构体 struct __user_cap_data_struct capdata[CAP_NUM]; // 定义能力数据结构体数组 struct __user_cap_data_struct capdatac[CAP_NUM]; // 定义另一个能力数据结构体数组,用于获取当前能力 struct timespec tp; // 定义时间结构体 int ret; // 定义返回值变量,此处漏写了初始化 // 初始化结构体 (void)memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct)); // 清零能力头部结构体 (void)memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct), 0, CAP_NUM * sizeof(struct __user_cap_data_struct)); // 清零能力数据结构体数组 capdata[0].permitted = 0xffffffff; // 设置允许的所有能力为全开 capdata[1].permitted = 0xffffffff; // 同上,第二个数据结构体也全开(虽然只用一个) capheader.version = _LINUX_CAPABILITY_VERSION_3; // 设置能力版本 // 设置能力的有效位 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETPCAP); // 允许修改进程能力 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETUID); // 允许改变用户ID capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_KILL); // 允许发送信号 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_TIME); // 允许改变系统时间 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); // 允许改变调度优先级 // 使用capset设置能力并检查返回值 ret = capset(&capheader, &capdata[0]); ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言capset返回0,表示成功 ret = capget(&capheader, &capdatac[0]); // 获取当前能力 ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言capget返回0,表示成功 capheader.pid = INVAILD_PID; // 设置一个无效的PID ret = capget(&capheader, &capdatac[0]); // 尝试获取无效PID的能力 ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言返回-1,表示失败 errno = 0; // 重置errno capheader.pid = 3; // 设置PID为3 kill(capheader.pid, 0); // 检查PID是否存在 if (errno != ESRCH) { // 如果PID存在 ret = capget(&capheader, &capdatac[0]); // 获取能力 ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功 printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); // 打印有效和允许的能力 } // 类似地,检查PID 4, 5, 6 errno = 0; capheader.pid = 4; kill(capheader.pid, 0); if (errno != ESRCH) { ret = capget(&capheader, &capdatac[0]); ICUNIT_ASSERT_EQUAL(ret, 0, ret); printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); } errno = 0; capheader.pid = 5; kill(capheader.pid, 0); if (errno != ESRCH) { ret = capget(&capheader, &capdatac[0]); ICUNIT_ASSERT_EQUAL(ret, 0, ret); printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); } errno = 0; capheader.pid = 6; kill(capheader.pid, 0); if (errno != ESRCH) { ret = capget(&capheader, &capdatac[0]); ICUNIT_ASSERT_EQUAL(ret, 0, ret); printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); } capheader.pid = 0; // 重置PID为0(当前进程) // 尝试重置子进程的UID int pid = fork(); // 创建子进程 if (pid == 0) { // 如果是子进程 ret = setuid(CHANGE_CHILD_UID); // 尝试改变用户ID ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功 Child(); // 执行子进程函数 } sleep(1); // 父进程等待1秒 ret = kill(pid, SIGXFSZ); // 尝试发送SIGXFSZ信号给子进程 ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功 // 移除KILL能力并再次尝试发送信号,应该失败 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_KILL); ret = capset(&capheader, &capdata[0]); // 更新能力 ret = kill(pid, SIGXFSZ); // 再次尝试发送信号 ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言失败 // 尝试设置系统时间,应该成功然后失败(移除SYS_TIME能力) tp.tv_sec = 0; // 设置时间为0 tp.tv_nsec = 0; // 纳秒部分也设置为0 ret = clock_settime(CLOCK_REALTIME, &tp); // 尝试设置时间 ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME); // 移除SYS_TIME能力 ret = capset(&capheader, &capdata[0]); // 更新能力 ret = clock_settime(CLOCK_REALTIME, &tp); // 再次尝试设置时间 ICUNIT_ASSERT_EQUAL(ret, -1, ret); // 断言失败 // 尝试改变子进程的调度优先级,应该成功然后失败(移除SYS_NICE能力) struct sched_param param = { 0 }; // 定义调度参数结构体 ret = sched_getparam(pid, ¶m); // 获取当前调度参数 param.sched_priority--; // 降低优先级 ret = sched_setparam(pid, ¶m); // 尝试设置新的调度参数 ICUNIT_ASSERT_EQUAL(ret, 0, ret); // 断言成功 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE); // 移除SYS_NICE能力 ret = capset(&capheader, &capdata[0]); // 更新能力 ret = sched_setparam(pid, ¶m); // 再次尝试设置调度参数 ICUNIT_ASSERT_EQUAL(ret, -1, ret); wait(nullptr); exit(92); return 0; } static int TestCase(VOID) { int ret; int status = 0; pid_t pid = fork(); ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); if (pid == 0) { ret = TestChild(); exit(__LINE__); } ret = waitpid(pid, &status, 0); ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT); status = WEXITSTATUS(status); ICUNIT_GOTO_EQUAL(status, 92, status, EXIT); return 0; EXIT: return 1; } void ItTestCap001(void) { TEST_ADD_CASE("IT_SEC_CAP_001", TestCase, TEST_POSIX, TEST_SEC, TEST_LEVEL0, TEST_FUNCTION); } --- .../capability/smoke/cap_test_001.cpp | 170 +++++++++--------- 1 file changed, 88 insertions(+), 82 deletions(-) diff --git a/kernel_liteos_a-master/testsuites/unittest/security/capability/smoke/cap_test_001.cpp b/kernel_liteos_a-master/testsuites/unittest/security/capability/smoke/cap_test_001.cpp index 26a9303..f4ba2e2 100644 --- a/kernel_liteos_a-master/testsuites/unittest/security/capability/smoke/cap_test_001.cpp +++ b/kernel_liteos_a-master/testsuites/unittest/security/capability/smoke/cap_test_001.cpp @@ -28,71 +28,74 @@ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include "pthread.h" -#include "linux/capability.h" -#include -#include "it_test_capability.h" -#include -#include -#include - -#define CAP_NUM 2 -#define INVAILD_PID 65535 -#define CHANGE_CHILD_UID 1000 - +#include "pthread.h" // POSIX߳̿⣬ڶ̱߳ +#include "linux/capability.h" // Linuxcapabilities壬Ȩ޿ +#include // ϵͳӿ +#include "it_test_capability.h" // DzԿܻصͷļ +#include // źŴ +#include // +#include // ʱ䴦 + +#define CAP_NUM 2 // ĴС +#define INVAILD_PID 65535 // һЧĽID +#define CHANGE_CHILD_UID 1000 // ӽҪĵûID + +// źŴǰΪʵ static void Sigac(int param) { return; } - + +// ӽ̺ static void Child() { - int i = 10; - signal(25, Sigac); - - while (i--) { + int i = 10; // ѭ + signal(25, Sigac); // ź25ĴΪSigac + + while (i--) { // ѭ10Σÿ˯1 sleep(1); } - //sleep for 10 second and exit; + // ˯10˳ exit(0); } - + +// ӽ̵ĺ static int TestChild(VOID) { - struct __user_cap_header_struct capheader; - struct __user_cap_data_struct capdata[CAP_NUM]; - struct __user_cap_data_struct capdatac[CAP_NUM]; - struct timespec tp; - int ret - //originalize struct - (void)memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct)); - (void)memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct), 0, - CAP_NUM * sizeof(struct __user_cap_data_struct)); - capdata[0].permitted = 0xffffffff; - capdata[1].permitted = 0xffffffff; - capheader.version = _LINUX_CAPABILITY_VERSION_3; - //set capbility to effective - capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETPCAP); - capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETUID); - capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_KILL); - capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_TIME); - capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); - //use capset to check and get info + struct __user_cap_header_struct capheader; // ͷṹ + struct __user_cap_data_struct capdata[CAP_NUM]; // ݽṹ + struct __user_cap_data_struct capdatac[CAP_NUM]; // һݽṹ飬ڻȡǰ + struct timespec tp; // ʱṹ + int ret; // 巵ֵ˴©д˳ʼ + // ʼṹ + (void)memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct)); // ͷṹ + (void)memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct), 0, CAP_NUM * sizeof(struct __user_cap_data_struct)); // ݽṹ + capdata[0].permitted = 0xffffffff; // Ϊȫ + capdata[1].permitted = 0xffffffff; // ͬϣڶݽṹҲȫȻֻһ + capheader.version = _LINUX_CAPABILITY_VERSION_3; // 汾 + // Чλ + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETPCAP); // ޸Ľ + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SETUID); // ıûID + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_KILL); // ź + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_TIME); // ıϵͳʱ + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective |= CAP_TO_MASK(CAP_SYS_NICE); // ıȼ + // ʹcapset鷵ֵ ret = capset(&capheader, &capdata[0]); - ICUNIT_ASSERT_EQUAL(ret, 0, ret); - ret = capget(&capheader, &capdatac[0]); - ICUNIT_ASSERT_EQUAL(ret, 0, ret); - capheader.pid = INVAILD_PID; - ret = capget(&capheader, &capdatac[0]); - ICUNIT_ASSERT_EQUAL(ret, -1, ret); - errno = 0; - capheader.pid = 3; - kill(capheader.pid, 0); - if (errno != ESRCH) { - ret = capget(&capheader, &capdatac[0]); - ICUNIT_ASSERT_EQUAL(ret, 0, ret); - printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); + ICUNIT_ASSERT_EQUAL(ret, 0, ret); // capset0ʾɹ + ret = capget(&capheader, &capdatac[0]); // ȡǰ + ICUNIT_ASSERT_EQUAL(ret, 0, ret); // capget0ʾɹ + capheader.pid = INVAILD_PID; // һЧPID + ret = capget(&capheader, &capdatac[0]); // ԻȡЧPID + ICUNIT_ASSERT_EQUAL(ret, -1, ret); // Է-1ʾʧ + errno = 0; // errno + capheader.pid = 3; // PIDΪ3 + kill(capheader.pid, 0); // PIDǷ + if (errno != ESRCH) { // PID + ret = capget(&capheader, &capdatac[0]); // ȡ + ICUNIT_ASSERT_EQUAL(ret, 0, ret); // Գɹ + printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); // ӡЧ } + // ƵأPID 4, 5, 6 errno = 0; capheader.pid = 4; kill(capheader.pid, 0); @@ -117,39 +120,42 @@ static int TestChild(VOID) ICUNIT_ASSERT_EQUAL(ret, 0, ret); printf("e %d,p %d\n", capdatac[0].effective, capdatac[0].permitted); } - capheader.pid = 0; - //try reset UID - int pid = fork(); - if (pid == 0) { - ret = setuid(CHANGE_CHILD_UID); - ICUNIT_ASSERT_EQUAL(ret, 0, ret); - Child(); + capheader.pid = 0; // PIDΪ0ǰ̣ + // ӽ̵UID + int pid = fork(); // ӽ + if (pid == 0) { // ӽ + ret = setuid(CHANGE_CHILD_UID); // ԸıûID + ICUNIT_ASSERT_EQUAL(ret, 0, ret); // Գɹ + Child(); // ִӽ̺ } - sleep(1); - ret = kill(pid, SIGXFSZ); - ICUNIT_ASSERT_EQUAL(ret, 0, ret); + sleep(1); // ̵ȴ1 + ret = kill(pid, SIGXFSZ); // ԷSIGXFSZźŸӽ + ICUNIT_ASSERT_EQUAL(ret, 0, ret); // Գɹ + // ƳKILLٴγԷźţӦʧ capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_KILL); - ret = capset(&capheader, &capdata[0]); - ret = kill(pid, SIGXFSZ); - ICUNIT_ASSERT_EQUAL(ret, -1, ret); - - tp.tv_sec = 0; - tp.tv_nsec = 0; - ret = clock_settime(CLOCK_REALTIME, &tp); - ICUNIT_ASSERT_EQUAL(ret, 0, ret); - capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME); - ret = capset(&capheader, &capdata[0]); - ret = clock_settime(CLOCK_REALTIME, &tp); - ICUNIT_ASSERT_EQUAL(ret, -1, ret); - - struct sched_param param = { 0 }; - ret = sched_getparam(pid, ¶m); - param.sched_priority--; - ret = sched_setparam(pid, ¶m); - ICUNIT_ASSERT_EQUAL(ret, 0, ret); - capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE); - ret = capset(&capheader, &capdata[0]); - ret = sched_setparam(pid, ¶m); + ret = capset(&capheader, &capdata[0]); // + ret = kill(pid, SIGXFSZ); // ٴγԷź + ICUNIT_ASSERT_EQUAL(ret, -1, ret); // ʧ + + // ϵͳʱ䣬ӦóɹȻʧܣƳSYS_TIME + tp.tv_sec = 0; // ʱΪ0 + tp.tv_nsec = 0; // 벿ҲΪ0 + ret = clock_settime(CLOCK_REALTIME, &tp); // ʱ + ICUNIT_ASSERT_EQUAL(ret, 0, ret); // Գɹ + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME); // ƳSYS_TIME + ret = capset(&capheader, &capdata[0]); // + ret = clock_settime(CLOCK_REALTIME, &tp); // ٴγʱ + ICUNIT_ASSERT_EQUAL(ret, -1, ret); // ʧ + + // Ըıӽ̵ĵȼӦóɹȻʧܣƳSYS_NICE + struct sched_param param = { 0 }; // Ȳṹ + ret = sched_getparam(pid, ¶m); // ȡǰȲ + param.sched_priority--; // ȼ + ret = sched_setparam(pid, ¶m); // µĵȲ + ICUNIT_ASSERT_EQUAL(ret, 0, ret); // Գɹ + capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE); // ƳSYS_NICE + ret = capset(&capheader, &capdata[0]); // + ret = sched_setparam(pid, ¶m); // ٴγõȲ ICUNIT_ASSERT_EQUAL(ret, -1, ret); wait(nullptr); exit(92);