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" // 引入Linux能力(capabilities)定义,用于权限控制 +#include // 引入系统能力接口 +#include "it_test_capability.h" // 假设是测试框架或测试相关的头文件 +#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); // 断言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); @@ -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);