SV.INCORRECT_RESOURCE_HANDLING.URH
不安全的资源处理 - 分配和释放
资源管理问题可导致过度消耗资源或耗尽资源。分配资源时,务必要正确地释放资源并且说明所有潜在的退出路径。类似的,代码需要跟踪资源的请求和释放情况,以保证不会请求已被释放的资源。此类型的漏洞通常出现在因异常或错误处理而退出函数时。
SV.INCORRECT_RESOURCE_HANDLING.URH 检查器会标记出请求可能已经被释放的资源的情况。检查器会分析以下 POSIX 资源,以查找错误的资源处理:
- 标准输入/输出资源:文件描述符、文件以及管道流
- X/开放式系统接口 (XSI) 资源:消息、信号灯,以及共享内存
- 实时资源:消息队列、信号灯、共享内存、已指定类型的内存对象、进程派生、时钟以及计时器
- 线程资源:线程、互斥、条件变量、障碍、读取/写入锁定对象以及旋转锁定对象
- 套接字
- 跟踪
有关详细信息,请参阅最新发布的“开放式组基本规范”。
漏洞与风险
虽然此情况并不是真正的安全性风险,但是不正确的错误处理可能导致软件可靠性问题,并且可能泄露敏感数据。如果攻击者可以蓄意地触发资源泄露,则资源库会被削减,直至导致拒绝服务 (DoS)。
缓解与预防
正确的做法是确保所有已分配的资源在随后都得到释放,并且与函数和应用程序中的资源分配与释放保持一致。特别是应始终检查错误条件,以确保适当地分配和释放资源。
漏洞代码示例
复制
#include <stdio.h>
#include <mqueue.h>
void message_released(const char* name, const char* data1, const char* data2)
{
char c;
mqd_t h;
if ((h = mq_open(name, O_RDWR)) != (mqd_t)-1)
{
mq_receive(h, &c, 1, NULL);
if (c == '1')
mq_send(h, data1, strlen(data1)+1, 2);
else
if (c == '2')
mq_send(h, data2, strlen(data2)+1, 2);
mq_close(h);
printf("OK.\n");
mq_send(h, "OK.", 3, 2); // ERROR
}
else
{
fprintf(stderr, "'mq_open' failed for %s\n", name);
}
}
Klocwork 针对第 20 行生成问题报告,表明处理程序 h(调用 mq_open 产生的结果)在第 18 行中被释放后使用。像这样不正确的资源处理可导致软件可靠性问题。
修正代码示例
复制
#include <stdio.h>
#include <mqueue.h>
void message_released(const char* name, const char* data1, const char* data2)
{
char c;
mqd_t h;
if ((h = mq_open(name, O_RDWR)) != (mqd_t)-1)
{
mq_receive(h, &c, 1, NULL);
if (c == '1')
mq_send(h, data1, strlen(data1)+1, 2);
else
if (c == '2')
mq_send(h, data2, strlen(data2)+1, 2);
printf("OK.\n");
mq_send(h, "OK.", 3, 2);
mq_close(h);
}
else
{
fprintf(stderr, "'mq_open' failed for %s\n", name);
}
}
在此修正代码示例中,调用 mq_send 之后,直至第 21 行才会释放处理程序 h。