* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _IT_PTHREAD_TEST_H // 防止头文件被重复包含
#define _IT_PTHREAD_TEST_H
#include "osTest.h" // 包含操作系统测试相关的头文件
#include <sys/resource.h> // 包含资源控制相关的头文件
#include <sys/wait.h> // 包含等待进程结束相关的头文件
#include <time.h> // 包含时间处理的头文件
#define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) // 定义宏,用于睡眠和让出CPU,tick为微秒单位
#include "sys/syscall.h" // 包含系统调用相关的头文件
// 定义一个内联函数,用于执行系统调用
static inline int Syscall(int nbr, int parm1, int parm2, int parm3, int parm4)
{
register int reg7 __asm__("r7") = nbr; // 将系统调用号放入寄存器r7
register int reg3 __asm__("r3") = parm4; // 将第四个参数放入寄存器r3
register int reg2 __asm__("r2") = parm3; // 将第三个参数放入寄存器r2
register int reg1 __asm__("r1") = parm2; // 将第二个参数放入寄存器r1
register int reg0 __asm__("r0") = parm1; // 将第一个参数放入寄存器r0
// 使用svc指令触发系统调用,将结果存回reg0
__asm__ __volatile__("svc 0" : "=r"(reg0) : "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) : "memory");
return reg0; // 返回系统调用的结果
}
// 声明全局变量,用于存储单元测试的错误码和错误行号
extern INT32 g_iCunitErrCode;
extern INT32 g_iCunitErrLineNo;
// 声明一系列pthread相关的测试函数
extern void ItTestPthread001(void); // pthread测试函数1
extern void ItTestPthread002(void); // pthread测试函数2
extern void ItTestPthread003(void); // pthread测试函数3
extern void ItTestPthread004(void); // pthread测试函数4
extern void ItTestPthread005(void); // pthread测试函数5
extern void ItTestPthread006(void); // pthread测试函数6
extern void ItTestPthread007(void); // pthread测试函数7
extern void ItTestPthread008(void); // pthread测试函数8
extern void ItTestPthread009(void); // pthread测试函数9
extern void ItTestPthread010(void); // pthread测试函数10
extern void ItTestPthread012(void); // 省略了11,可能是个错误或者遗漏
extern void ItTestPthread011(void); // pthread测试函数11
extern void ItTestPthread013(void); // pthread测试函数13
extern void ItTestPthread014(void); // pthread测试函数14
extern void ItTestPthread015(void); // pthread测试函数15
extern void ItTestPthread016(void); // pthread测试函数16
extern void ItTestPthread017(void); // pthread测试函数17
extern void ItTestPthread018(void); // pthread测试函数18
extern void ItTestPthread019(void); // pthread测试函数19
extern void ItTestPthread020(void); // pthread测试函数20
extern void ItTestPthread021(void); // pthread测试函数21
extern void ItTestPthread022(void); // pthread测试函数22
extern void ItTestPthread023(void); // pthread测试函数23
extern void ItTestPthread024(void); // pthread测试函数24
extern void ItTestPthread025(void); // pthread测试函数25
extern void ItTestPthread026(void); // pthread测试函数26
extern void ItTestPthread027(void); // pthread测试函数27
extern void ItTestPthreadAtfork001(void); // pthread atfork测试函数1
extern void ItTestPthreadAtfork002(void); // pthread atfork测试函数2
extern void ItTestPthreadOnce001(void); // pthread once测试函数1
extern void ItTestPthreadCond001(void); // pthread 条件变量测试函数1
extern void ItTestPthreadCond002(void); // pthread 条件变量测试函数2
extern void ItTestPthreadCond003(void); // pthread 条件变量测试函数3
extern void ItTestPthreadCond004(void); // pthread 条件变量测试函数4
#endif // 结束头文件保护
代码修改
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used * to endorse or promote products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "pthread.h" // 引入POSIX线程库,用于多线程编程 #include "linux/capability.h" // 引入Linux能力(capabilities)定义,用于权限控制 #include <sys/capability.h> // 引入系统能力接口 #include "it_test_capability.h" // 假设是测试框架或测试相关的头文件 #include <signal.h> // 引入信号处理函数 #include <sys/types.h> // 引入基本数据类型 #include <time.h> // 引入时间处理函数 #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); }* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, this list of * conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, this list * of conditions and the following disclaimer in the documentation and/or other materials * provided with the distribution. * * 3. Neither the name of the copyright holder nor the names of its contributors may be used * to endorse or promote products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #ifndef _IT_PTHREAD_TEST_H // 防止头文件被重复包含 #define _IT_PTHREAD_TEST_H #include "osTest.h" // 包含操作系统测试相关的头文件 #include <sys/resource.h> // 包含资源控制相关的头文件 #include <sys/wait.h> // 包含等待进程结束相关的头文件 #include <time.h> // 包含时间处理的头文件 #define SLEEP_AND_YIELD(tick) usleep((tick)*10 * 1000) // 定义宏,用于睡眠和让出CPU,tick为微秒单位 #include "sys/syscall.h" // 包含系统调用相关的头文件 // 定义一个内联函数,用于执行系统调用 static inline int Syscall(int nbr, int parm1, int parm2, int parm3, int parm4) { register int reg7 __asm__("r7") = nbr; // 将系统调用号放入寄存器r7 register int reg3 __asm__("r3") = parm4; // 将第四个参数放入寄存器r3 register int reg2 __asm__("r2") = parm3; // 将第三个参数放入寄存器r2 register int reg1 __asm__("r1") = parm2; // 将第二个参数放入寄存器r1 register int reg0 __asm__("r0") = parm1; // 将第一个参数放入寄存器r0 // 使用svc指令触发系统调用,将结果存回reg0 __asm__ __volatile__("svc 0" : "=r"(reg0) : "r"(reg7), "r"(reg0), "r"(reg1), "r"(reg2), "r"(reg3) : "memory"); return reg0; // 返回系统调用的结果 } // 声明全局变量,用于存储单元测试的错误码和错误行号 extern INT32 g_iCunitErrCode; extern INT32 g_iCunitErrLineNo; // 声明一系列pthread相关的测试函数 extern void ItTestPthread001(void); // pthread测试函数1 extern void ItTestPthread002(void); // pthread测试函数2 extern void ItTestPthread003(void); // pthread测试函数3 extern void ItTestPthread004(void); // pthread测试函数4 extern void ItTestPthread005(void); // pthread测试函数5 extern void ItTestPthread006(void); // pthread测试函数6 extern void ItTestPthread007(void); // pthread测试函数7 extern void ItTestPthread008(void); // pthread测试函数8 extern void ItTestPthread009(void); // pthread测试函数9 extern void ItTestPthread010(void); // pthread测试函数10 extern void ItTestPthread012(void); // 省略了11,可能是个错误或者遗漏 extern void ItTestPthread011(void); // pthread测试函数11 extern void ItTestPthread013(void); // pthread测试函数13 extern void ItTestPthread014(void); // pthread测试函数14 extern void ItTestPthread015(void); // pthread测试函数15 extern void ItTestPthread016(void); // pthread测试函数16 extern void ItTestPthread017(void); // pthread测试函数17 extern void ItTestPthread018(void); // pthread测试函数18 extern void ItTestPthread019(void); // pthread测试函数19 extern void ItTestPthread020(void); // pthread测试函数20 extern void ItTestPthread021(void); // pthread测试函数21 extern void ItTestPthread022(void); // pthread测试函数22 extern void ItTestPthread023(void); // pthread测试函数23 extern void ItTestPthread024(void); // pthread测试函数24 extern void ItTestPthread025(void); // pthread测试函数25 extern void ItTestPthread026(void); // pthread测试函数26 extern void ItTestPthread027(void); // pthread测试函数27 extern void ItTestPthreadAtfork001(void); // pthread atfork测试函数1 extern void ItTestPthreadAtfork002(void); // pthread atfork测试函数2 extern void ItTestPthreadOnce001(void); // pthread once测试函数1 extern void ItTestPthreadCond001(void); // pthread 条件变量测试函数1 extern void ItTestPthreadCond002(void); // pthread 条件变量测试函数2 extern void ItTestPthreadCond003(void); // pthread 条件变量测试函数3 extern void ItTestPthreadCond004(void); // pthread 条件变量测试函数4 #endif // 结束头文件保护82512f98ecinto master 10 months ago82512f98ec.