### Handle String Normalization with Sufficient Buffer (realpath) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md When normalizing paths with realpath, ensure the provided buffer is adequate or allow the system to allocate memory. This example demonstrates both approaches. ```C #define MAX_PATH_LEN 100 char resolved_path[MAX_PATH_LEN]; /* - realpath函数的存储缓冲区长度是由PATH_MAX常量定义, - 或是由_PC_PATH_MAX系统值配置的,通常都大于100字节 */ char *res = realpath(path, resolved_path); ... ``` ```C char *resolved_path = NULL; resolved_path = realpath(path, NULL); if (resolved_path == NULL) { ... // 处理错误 } ... if (resolved_path != NULL) { free(resolved_path); resolved_path = NULL; } ... ``` -------------------------------- ### Prevent Integer Overflow in Division (C) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This example demonstrates how to prevent integer overflow during division. It includes checks for division by zero and for the specific case where dividing INT_MIN by -1 would cause an overflow. ```C int num_a = ... // 来自外部数据 int num_b = ... // 来自外部数据 int result = 0; // 检查除数为0及除法溢出错误 if ((num_b == 0) || ((num_a == INT_MIN) && (num_b == -1))) { ... // 错误处理 } result = num_a / num_b; ... ``` -------------------------------- ### Ensure Sufficient Buffer Space for String Conversions (itoa) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md When converting numbers to strings using functions like itoa, ensure the destination buffer is large enough to hold the resulting string and its null terminator. This example shows the correct buffer size allocation. ```C int num = ... char str[8]; itoa(num, str, 10); // 10进制整数的最大存储长度是12个字节 ``` ```C int num = ... char str[13]; itoa(num, str, 10); // 10进制整数的最大存储长度是12个字节 ``` -------------------------------- ### Explicitly Set File Access Permissions on Creation Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md When creating files using functions like POSIX open(), always explicitly specify the desired file access permissions (e.g., read/write for owner only) to prevent unintended access or modification by unauthorized users. This example shows using S_IRUSR | S_IWUSR. ```c void foo(void) { int fd = -1; char *file_name = NULL; ... fd = open(file_name, O_CREAT | O_WRONLY); // 没有显式指定访问权限 if (fd == -1) { ... } ... } ``` ```c void foo(void) { int fd = -1; char *file_name = NULL; ... // 此处根据文件实际需要,显式指定其访问权限 int fd = open(file_name, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR); if (fd == -1) { ... } ... } ``` -------------------------------- ### Correctly Get Array Size Instead of Pointer Size Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Avoid using sizeof on a pointer when intending to get the size of the array it points to. This example corrects a memset operation that used the wrong size. ```C char path[MAX_PATH]; char *buffer = (char *)malloc(SIZE); ... (void)memset(path, 0, sizeof(path)); // sizeof与预期不符,其结果为指针本身的大小而不是缓冲区大小 (void)memset(buffer, 0, sizeof(buffer)); ``` ```C char path[MAX_PATH]; char *buffer = (char *)malloc(SIZE); ... (void)memset(path, 0, sizeof(path)); (void)memset(buffer, 0, SIZE); // 使用申请的缓冲区大小 ``` -------------------------------- ### Zero Out Password Buffer After Use Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md After a password has been used for verification or other sensitive operations, it should be cleared from memory using memset to prevent potential exposure. This example demonstrates clearing a password buffer after validation. ```c int foo(void) { char password [MAX_PWD_LEN ] = {0}; if (!get_password(password, sizeof(password))) { ... } if (!verify_password(password)) { ... } ... (void)memset(password, 0, sizeof(password)); ... } ``` -------------------------------- ### Incorrectly Handling Address Validation Restoration on Error Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This example shows an error scenario where the address validation mechanism is not restored after a system call fails. Failing to reset the address limit in error handling paths can leave security mechanisms like SMEP/PXN vulnerable. ```c ... oldfs = get_fs(); set_fs(KERNEL_DS); /* 在时间戳目录下面创建done文件 */ fd = sys_open(path, O_CREAT | O_WRONLY, FILE_LIMIT); if (fd < 0) { BB_PRINT_ERR("sys_mkdir[%s] error, fd is[%d]\n", path, fd); return; // 错误:在错误处理程序分支未恢复地址校验机制 } sys_close(fd); set_fs(oldfs); ... ``` -------------------------------- ### Prevent Integer Overflow in Subtraction (C) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This example shows how to prevent integer overflow in subtraction, particularly when calculating buffer sizes for memory operations like memmove. It ensures that the lengths used are within valid bounds and that subtraction does not result in an underflow. ```C unsigned char *content = ... //指向报文头的指针 size_t content_size = ... // 缓冲区的总长度 size_t total_len = ... // 报文总长度 size_t skip_len = ... // 从消息中解析出来的需要忽略的数据长度 if (skip_len >= total_len || total_len > content_size) { ... // 错误处理 } (void)memmove(content, content + skip_len, total_len - skip_len); ... ``` -------------------------------- ### Prevent Array Index Out-of-Bounds Errors Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Ensure array indices are within the valid range to prevent out-of-bounds writes or reads. This example corrects off-by-one errors in index checks. ```C #define DEV_NUM 10 #define MAX_NAME_LEN 128 typedef struct { int id; char name[MAX_NAME_LEN]; } Dev; static Dev devs[DEV_NUM]; int set_dev_id(size_t index, int id) { if (index > DEV_NUM) { // 错误:差一错误。 ... // 错误处理 } devs[index].id = id; return 0; } static Dev *get_dev(size_t index) { if (index > DEV_NUM) { // 错误:差一错误。 ... // 错误处理 } return devs + index; } ``` ```C #define DEV_NUM 10 #define MAX_NAME_LEN 128 typedef struct { int id; char name[MAX_NAME_LEN]; } Dev; static Dev devs[DEV_NUM]; int set_dev_Id (size_t index, int id) { if (index >= DEV_NUM) { ... // 错误处理 } devs[index].id = id; return 0; } static Dev *get_dev(size_t index) { if (index >= DEV_NUM) { ... // 错误处理 } return devs + index; } ``` -------------------------------- ### Ensure Null Termination After String Copy Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md When copying strings, especially with functions like strncpy that might truncate, always ensure the destination buffer is null-terminated. This example shows how to correctly handle string copying to prevent potential buffer overflows. ```C #define FILE_NAME_LEN 128 char file_name [FILE_NAME_LEN ]; (void)strncpy(file_name, name, sizeof(file_name) - 1); ... ``` ```C #define FILE_NAME_LEN 128 char file_name[FILE_NAME_LEN ]; if (strlen(name) > FILE_NAME_LEN - 1) { ... // 处理错误 } (void)strcpy(file_name, name); ... ``` -------------------------------- ### Prevent Integer Overflow in Unary Minus (C) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This example demonstrates how to prevent integer overflow when applying the unary minus operator. It specifically checks if the operand is the minimum value for a signed integer type, as negating it would cause an overflow. ```C int num_a = ... // 来自外部数据 int result = 0; if (num_a == LNT_MIN) { ... // 错误处理 } result = -num_a; ... ``` -------------------------------- ### Validate External Input for Memory Copy Length Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md When external input indirectly influences memory copy operations (e.g., loop bounds), validate its size against the target buffer capacity to prevent buffer overflows. This example shows validating a count before using it in a loop that copies data. ```c typedef struct { size_t count; int val[MAX_num_bERS]; } ValueTable; ValueTable *value_table_dup(const ValueTable *input_table) { ValueTable *output_table = ... // 分配内存 ... for (size_t i = 0; i < input_table->count; i++) { output_table->val[i] = input_table->val[i]; } ... } ``` ```c typedef struct { size_t count; int val[MAX_num_bERS]; }ValueTable; ValueTable *value_table_dup(const ValueTable *input_table) { ValueTable *output_table = ... // 分配内存 ... / * - 根据应用场景,对来自外部报文的循环长度input_table->count - 与output_table->val数组大小做校验,避免造成缓冲区溢出 */ if (input_table->count > sizeof(output_table->val) / sizeof(output_table->val[0]){ return NULL; } for (size_t i = 0; i < input_table->count; i++) { output_table->val[i] = input_table->val[i]; } ... } ``` -------------------------------- ### Using set_fs and get_fs for File Operations in Kernel Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This snippet demonstrates how to temporarily disable address validation for system calls within a kernel module, allowing it to write to a file. It highlights the correct procedure of saving the original address limit, setting it to KERNEL_DS, performing the operation, and then restoring the original limit. ```c mmegment_t old_fs; printk("Hello, I'm the module that intends to write message to file.\n"); if (file == NULL) { file = filp_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT, 0664); } if (IS_ERR(file)) { printk("Error occured while opening file %s, exiting ...\n", MY_FILE); return 0; } sprintf(buf, "%s", "The Message."); old_fs = get_fs(); // get_fs()的作用是获取用户空间地址上限值 // #define get_fs() (current->addr_limit set_fs(KERNEL_DS); // set_fs的作用是将地址空间上限扩大到KERNEL_DS,这样内核代码可以调用系统函数 file->f_op->write(file, (char *)buf, sizeof(buf), &file->f_pos); // 内核代码可以调用write()函数 set_fs(old_fs); // 使用完后及时恢复原来用户空间地址限制值 ... ``` -------------------------------- ### Correctly Restoring Address Validation in Error Handling Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This snippet demonstrates the correct way to handle address validation restoration within an error handling branch. It ensures that set_fs(oldfs) is called even when sys_open fails, maintaining the integrity of security mechanisms. ```c ... oldfs = get_fs(); set_fs(KERNEL_DS); /* 在时间戳目录下面创建done文件 */ fd = sys_open(path, O_CREAT | O_WRONLY, FILE_LIMIT); if (fd < 0) { BB_PRINT_ERR("sys_mkdir[%s] error, fd is[%d] \n", path, fd); set_fs(oldfs); // 修改:在错误处理程序分支中恢复地址校验机制 return; } sys_close(fd); set_fs(oldfs); ... ``` -------------------------------- ### Correctly Match printf Format Specifiers Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Ensure that the arguments provided to printf match the format specifiers in the format string. Mismatched types can lead to undefined behavior, memory corruption, or program termination. ```C void foo(void) { const char *info_msg = "Information seed to user."; int info_level = 3; ... printf("infoLevel: %s, infoMsg: %d\n", info_level, info_msg); ... } ``` ```C void foo(void) { const char *info_msg = "Information seed to user."; int info_level = 3; ... printf("infoLevel: %d, infoMsg: %s\n", info_level, info_msg); ... } ``` -------------------------------- ### Prohibit Use of Uninitialized Local Variables Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Ensure local variables and dynamically allocated memory are initialized before their values are read. Uninitialized variables have unpredictable values, leading to potential errors. ```c void foo( ...) { int data; bar(data); // 错误:未初始化就使用 ... } ``` ```c #define CUSTOMIZED_SIZE 100 void foo( ...) { int data; if (condition > 0) { data = CUSTOMIZED_SIZE; } bar(data); // 错误:部分分支该值未初始化 ... } ``` -------------------------------- ### Prevent Format String Vulnerabilities with syslog Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Avoid format string vulnerabilities when using syslog by not using external data directly as the format string. Pass user input as an argument with a fixed format string like '%s'. ```C void foo(void) { char *msg = get_msg(); ... syslog(LOG_INFO, msg); // 存在格式化漏洞 } ``` ```C void foo(void) { static const char msg_format[] = "%s cannot be authenticated.\n"; char *msg = get_msg(); ... syslog(LOG_INFO, msg_format, msg); // 这里没有格式化漏洞 } ``` -------------------------------- ### Prevent Format String Vulnerabilities with fprintf Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Avoid format string vulnerabilities by ensuring user-controlled input is not directly used as the format string in fprintf. Use fputs for direct output or pass user input as an argument with a fixed format string like '%s'. ```C void incorrect_password(const char *user) { int ret = -1; static const char msg_format[] = "%s cannot be authenticated.\n"; size_t len = strlen(user) + 1 + sizeof(msg_format); char *msg = (char *)malloc(len); if (msg == NULL) { ... // 错误处理 } ret = snprintf(msg, msg_format, user); if (ret == -1) { ... // 错误处理 } else { fprintf(stderr, msg); // msg中有来自未验证的外部数据,存在格式化漏洞 } free(msg); } ``` ```C void incorrect_password(const char *user) { int ret = -1; static const char msg_format[] = "%s cannot be authenticated.\n"; // 这里加法运算不会整数溢出,因为user有限制 size_t len = strlen(user) + 1 + sizeof(msg_format); char *msg = (char *)malloc(len); if (msg == NULL) { ... // 错误处理 } ret = snprintf(msg, msg_format, user); if (ret == -1) { ... // 错误处理 } else { fputs(stderr, msg); // 使用fputs函数代替fprintf函数 } free(msg); } ``` ```C void incorrect_password(const char *user) { static const char msg_format[] = "%s cannot be authenticated.\n"; fprintf(stderr, msg_format, user); } ``` -------------------------------- ### Avoid alloca() for Stack Memory Allocation Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Do not use the alloca() function for allocating memory on the stack. It is non-standard, may reduce portability, and can easily lead to stack overflows, causing undefined behavior. -------------------------------- ### Clear Sensitive Information from Memory Before Freeing Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Sensitive information stored in dynamically allocated memory should be zeroed out before the memory is freed to prevent accidental leaks. This applies to passwords, keys, and other confidential data. ```c char *secret = NULL; / * - 假设 secret 指向敏感信息,敏感信息的内容是长度小于SIZE_MAX个字符, - 并且以null终止的字节字符串 */ size_t size = strlen(secret); char *new_secret = NULL; new_secret = (char *)malloc(size + 1); if (new_secret == NULL) { ... } else { strcpy(new_secret, secret); ... free(new_secret); new_secret = NULL; } ... ``` ```c char *secret = NULL; / * - 假设 secret 指向敏感信息,敏感信息的内容是长度小于SIZE_MAX个字符, - 并且以null终止的字节字符串 */ size_t size = strlen(secret); char *new_secret = NULL; new_secret = (char *)malloc(size + 1); if (new_secret == NULL) { ... } else { strcpy(new_secret, secret); ... (void)memset(new_secret, 0, size + 1); free(new_secret); new_secret = NULL; } ... ``` -------------------------------- ### Prevent Unsigned Integer Wrap-around in Addition Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Avoid integer wrap-around in addition by checking if the potential next length exceeds the total length. This prevents bypassing security checks. ```c size_t total_len = ... // 报文的总长度 size_t read_len = 0 // 记录已经处理报文的长度 ... size_t pkt_len = parse_pkt_len(); // 从网络报文中解析出来的下一个子报文的长度 if (read_len + pkt_len > total_len) { // 可能出现整数回绕 ... // 错误处理 } ... read_len += pkt_len; ... ``` ```c size_t total_len = ... // 报文的总长度 size_t read_len = 0; // 记录已经处理报文的长度 ... size_t pkt_len = parse_pkt_len(); // 来自网络报文 if (pkt_len > total_len - read_len) { ... // 错误处理 } ... read_len += pkt_len; ... ``` -------------------------------- ### Prevent Division by Zero in Signed Integer Modulo Operation Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Prevent division by zero errors in signed integer modulo operations by checking if the divisor is zero. This is crucial as modulo and division often share underlying instructions. ```c int num_a = ... // 来自外部数据 int num_b = ... // 来自外部数据 int result = 0; if ((num_a == INT_MIN) && (num_b == -1)) { ... // 错误处理 } result = num_a % num_b; // 可能出现除零错误 ... ``` ```c int num_a = ... // 来自外部数据 int num_b = ... // 来自外部数据 int result = 0; if ((num_b == 0) | | ((num_a == INT_MIN) && (num_b == -1))) { ... // 错误处理 } result = num_a % num_b; ... ``` -------------------------------- ### Set Pointers to NULL After Freeing Memory Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md After freeing memory pointed to by a pointer, immediately set the pointer to NULL to prevent it from becoming a dangling pointer. This avoids double-free or use-after-free vulnerabilities. ```c int foo(void) { SomeStruct *msg = NULL; ... // 初始化msg->type,分配 msg->body 的内存空间 if (msg->type == MESSAGE_A) { ... free(msg->body); } ... EXIT: ... free(msg->body); return ret; } ``` ```c int foo(void) { SomeStruct *msg = NULL; ... // 初始化msg->type,分配 msg->body 的内存空间 if (msg->type == MESSAGE_A) { ... free(msg->body); msg->body = NULL; } ... EXIT: ... free(msg->body); return ret; } ``` -------------------------------- ### Handle realloc() Failures Safely Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md When using realloc(), always store the result in a temporary pointer before assigning it back to the original pointer. This prevents memory leaks if realloc() fails and returns NULL. ```C // 当realloc()分配内存失败时会返回NULL,导致内存泄漏 char *ptr = (char *)realloc(ptr, NEW_SIZE); if (ptr == NULL) { ...// 错误处理 } ``` ```C // 使用malloc()函数代替realloc()函数 char *new_ptr = (char *)malloc(NEW_SIZE); if (new_ptr == NULL) { ... // 错误处理 } (void)memcpy(new_ptr, old_ptr, old_size); ... // 返回前,释放old_Ptr ``` -------------------------------- ### Prevent Integer Overflow in Addition (C) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This snippet demonstrates how to prevent integer overflow during addition when dealing with external data. It checks if adding two numbers would exceed the maximum or minimum integer limits before performing the operation. ```C int num_a = ... // 来自外部数据 int num_b = ... // 来自外部数据 int sum = 0; if (((num_a > 0) && (num_b > (INT_MAX - num_a))) || ((num_a < 0) && (num_b < (INT_MIN - num_a)))) { ... // 错误处理 } sum = num_a + num_b; ... ``` -------------------------------- ### Prevent Integer Overflow in Multiplication (C) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This snippet addresses integer overflow in multiplication. It shows how to correctly validate input values against potential overflow before multiplying, using appropriate type casting or maximum value checks. ```C unsigned long opt = ... // 将类型重构为 unsigned long 类型。 if (opt > (ULONG_MAX / (60 * HZ))) { return -EINVAL; } ... = opt * 60 * HZ; ... ``` ```C int opt = ... // 来自用户态 if ((opt < 0) || (opt > (INT_MAX / (60 * HZ)))) { // 修改使用INT_MAX作为上限值 return -EINVAL; } ... = opt * 60 * HZ; ``` -------------------------------- ### Prevent Integer Overflow in Modulo Operation (C) Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md This snippet shows how to prevent integer overflow when using the modulo operator. Similar to division, it includes checks for division by zero and the INT_MIN % -1 overflow case. ```C int num_a = ... // 来自外部数据 int num_b = ... // 来自外部数据 int result = 0; // 检查除数为0及除法溢出错误 if ((num_b == 0) || ((num_a == INT_MIN) && (num_b == -1))) { ... // 错误处理 } result = num_a % num_b; ... } ``` -------------------------------- ### Prevent Division by Zero in Signed Integer Division Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Prevent division by zero errors in signed integer division by explicitly checking if the divisor is zero before performing the operation. This also handles the edge case of INT_MIN divided by -1. ```c int num_a = ... // 来自外部数据 int num_b = ... // 来自外部数据 int result = 0; if ((num_a == INT_MIN) && (num_b == -1)) { ... // 错误处理 } result = num_a / num_b; // 可能出现除零错误 ... ``` ```c int num_a = ... // 来自外部数据 int num_b = ... // 来自外部数据 int result = 0; if ((num_b == 0) | | ((num_a == INT_MIN) && (num_b == -1))) { ... // 错误处理 } result = num_a / num_b; ... ``` -------------------------------- ### Reset Resource Handles After Closing Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md After closing a resource handle (like sockets or file descriptors), immediately reset the associated variable to its invalid state (e.g., INVALID_SOCKET, -1). This prevents using a closed handle. ```c SOCKET s = INVALID_SOCKET; int fd = -1; ... closesocket(s); ... close(fd); ... ``` ```c SOCKET s = INVALID_SOCKET; int fd = -1; ... closesocket(s); s = INVALID_SOCKET; ... close(fd); fd = -1; ... ``` -------------------------------- ### Prevent Unsigned Integer Wrap-around in Multiplication Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Avoid integer wrap-around in multiplication when calculating memory allocation sizes. Check if the product of width and height exceeds the maximum size limit. ```c size_t width = ... // 来自外部数据 size_t hight = ... // 来自外部数据 unsigned char *buf = (unsigned char *)malloc(width * hight); ``` ```c size_t width = ... // 来自外部数据 size_t hight = ... // 来自外部数据 if (width == 0 || hight == 0) { ... // 错误处理 } if (width > SIZE_MAX / hight) { ... // 错误处理 } unsigned char *buf = (unsigned char *)malloc(width * hight); ``` -------------------------------- ### Prevent Unsigned Integer Wrap-around in Subtraction Source: https://github.com/kunpengcompute/kunpeng/blob/master/security/SecureCoding.md Prevent integer wrap-around in subtraction by ensuring the value to be subtracted does not exceed the maximum allowed value. This avoids bypassing length validation. ```c size_t len = ... // 来自用户态输入 if (SCTP_SIZE_MAX - len < sizeof(SctpAuthBytes)) { // 减法操作可能出现整数回绕 ... // 错误处理 } ... = kmalloc(sizeof(SctpAuthBytes) + len, gfp); // 可能出现整数回绕 ... ``` ```c size_t len = ... // 来自用户态输入 if (len > SCTP_SIZE_MAX - sizeof(SctpAuthBytes)) { // 确保编译期间减法表达式的值不翻转 ... // 错误处理 } ... = kmalloc(sizeof(SctpAuthBytes) + len, gfp); ... ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.