使用映射的共享内存获取 "out-of-bounds" 和 "variable uninitialized" 警告
Getting "out-of-bounds" and "variable uninitialized" warnings with mapped shared memory
作为 Linux 的 C 应用程序的一部分,我编写了一个小型库以允许不同进程通过共享内存区域进行通信。
我有很多关于潜在越界指针和我以此方式创建的内存区域中包含的潜在未初始化变量的警报。
考虑我写的创建共享内存区域的函数:
int LayOutShm (const char *shm_key, size_t memory_size, void ** new_memory)
{
int fd_value = 0;
void * pshm = NULL;
int return_value = MEM_MGMT_SHM_ERROR;
/* Force new_buffer pointer to NULL just like we initialize return_value to MEM_MGMT_SHM_ERROR */
*new_memory = NULL;
/* Shared object is created with O_EXCL to prevent two namesake areas from being created*/
fd_value = shm_open(shm_key, O_CREAT | O_RDWR | O_EXCL , S_IRWXU);
if(fd_value > 0){
if(ftruncate(fd_value, memory_size) == 0){
/* Here is where we get the pointer to the created memory area */
pshm = mmap(NULL, memory_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_value, 0);
if(pshm != MAP_FAILED){
return_value = MEM_MGMT_SHM_OK;
memset(pshm,0,memory_size); /* Initialize the memory area */
*new_memory = pshm; /* Pass the pointer back to the caller */
}
}
}
return return_value;
}/*LayOutShm*/
现在,这是我收到警告的一段代码:
#define SHM_KEY "my_shm_key"
typedef struct{
pthread_mutex_t shm_mutex;
int shm_var1;
char shm_var2;
union{
int shm_union_var1;
char shm_union_var2;
}shm_union
}t_shm_area;
static t_shm_area * shm_area = NULL;
static int ShmInitialization(void)
{
int return_value = -1;
(void)LayOutShm(SHM_KEY, sizeof(t_shm_area), (void**)&shm_area);
/*Check for errors in shared memory creation*/
if (shm_area == NULL){
syslog(LOG_ERR | LOG_USER, "Error laying out shared memory segment\n");
}
else{
shm_area->var1 = 0; /* This assignment gets flagged with a potential out-of-bounds runtime error */
shm_area->shm_union.shm_union_var2 = 0; /* This assignment gets flagged with a potential out-of-bounds runtime error */
/*Create empty attributes structure*/
pthread_mutexattr_t mutex_attributes;
/*Initialize attributes structures with default values*/
(void)pthread_mutexattr_init(&mutex_attributes);
/*Set attributes structure with shared memory value*/
(void)pthread_mutexattr_setpshared(&mutex_attributes, PTHREAD_PROCESS_SHARED);
/*settype mutex PTHREAD_MUTEX_ERRORCHECK*/
(void)pthread_mutexattr_settype(&mutex_attributes, PTHREAD_MUTEX_ERRORCHECK);
/*Initialize the mutex with all the previous attributes*/
(void)pthread_mutex_init(&shm_area->shm_mutex, &mutex_attributes);
return_value = 0;
}
return return_value;
}/*ShmInitialization*/
这是我第一次尝试使用双指针,所以如果我在声明中使用 void ** 或将输入双指针转换为的方式搞砸了,我不会感到惊讶无效。
该函数的先前实现 return 直接编辑了指针并没有产生这些问题,但我被要求更改它以便我们可以 return 状态代码(即使我们暂时不使用它们)。
创建该区域后,我传递给库以从共享内存中获取值的任何本地声明的变量都会得到 "tainted",并带有来自潜在 "out-of-bounds" 运行时错误或 "variable might not be initialized" 的警告警告。该库已经用几种不同类型的数据结构(其中一些大到 15kB)进行了测试,数据完整性和性能令人满意。
知道为什么我会收到这些警告吗?
非常感谢,祝好!
C 中的通用指针类型是 void*
。然而,没有通用的指针到指针类型 void**
。所以强制转换 (void**)&shm_area
是不兼容指针类型之间的强制转换。从技术上讲,这是未定义的行为(严格的别名违规),所以任何事情都有可能发生。
要解决此问题,请使用临时 void*
作为参数传递:
void* vptr = shm_area;
LayOutShm(...&vptr);
shm_area = vptr;
作为 Linux 的 C 应用程序的一部分,我编写了一个小型库以允许不同进程通过共享内存区域进行通信。
我有很多关于潜在越界指针和我以此方式创建的内存区域中包含的潜在未初始化变量的警报。
考虑我写的创建共享内存区域的函数:
int LayOutShm (const char *shm_key, size_t memory_size, void ** new_memory)
{
int fd_value = 0;
void * pshm = NULL;
int return_value = MEM_MGMT_SHM_ERROR;
/* Force new_buffer pointer to NULL just like we initialize return_value to MEM_MGMT_SHM_ERROR */
*new_memory = NULL;
/* Shared object is created with O_EXCL to prevent two namesake areas from being created*/
fd_value = shm_open(shm_key, O_CREAT | O_RDWR | O_EXCL , S_IRWXU);
if(fd_value > 0){
if(ftruncate(fd_value, memory_size) == 0){
/* Here is where we get the pointer to the created memory area */
pshm = mmap(NULL, memory_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_value, 0);
if(pshm != MAP_FAILED){
return_value = MEM_MGMT_SHM_OK;
memset(pshm,0,memory_size); /* Initialize the memory area */
*new_memory = pshm; /* Pass the pointer back to the caller */
}
}
}
return return_value;
}/*LayOutShm*/
现在,这是我收到警告的一段代码:
#define SHM_KEY "my_shm_key"
typedef struct{
pthread_mutex_t shm_mutex;
int shm_var1;
char shm_var2;
union{
int shm_union_var1;
char shm_union_var2;
}shm_union
}t_shm_area;
static t_shm_area * shm_area = NULL;
static int ShmInitialization(void)
{
int return_value = -1;
(void)LayOutShm(SHM_KEY, sizeof(t_shm_area), (void**)&shm_area);
/*Check for errors in shared memory creation*/
if (shm_area == NULL){
syslog(LOG_ERR | LOG_USER, "Error laying out shared memory segment\n");
}
else{
shm_area->var1 = 0; /* This assignment gets flagged with a potential out-of-bounds runtime error */
shm_area->shm_union.shm_union_var2 = 0; /* This assignment gets flagged with a potential out-of-bounds runtime error */
/*Create empty attributes structure*/
pthread_mutexattr_t mutex_attributes;
/*Initialize attributes structures with default values*/
(void)pthread_mutexattr_init(&mutex_attributes);
/*Set attributes structure with shared memory value*/
(void)pthread_mutexattr_setpshared(&mutex_attributes, PTHREAD_PROCESS_SHARED);
/*settype mutex PTHREAD_MUTEX_ERRORCHECK*/
(void)pthread_mutexattr_settype(&mutex_attributes, PTHREAD_MUTEX_ERRORCHECK);
/*Initialize the mutex with all the previous attributes*/
(void)pthread_mutex_init(&shm_area->shm_mutex, &mutex_attributes);
return_value = 0;
}
return return_value;
}/*ShmInitialization*/
这是我第一次尝试使用双指针,所以如果我在声明中使用 void ** 或将输入双指针转换为的方式搞砸了,我不会感到惊讶无效。
该函数的先前实现 return 直接编辑了指针并没有产生这些问题,但我被要求更改它以便我们可以 return 状态代码(即使我们暂时不使用它们)。
创建该区域后,我传递给库以从共享内存中获取值的任何本地声明的变量都会得到 "tainted",并带有来自潜在 "out-of-bounds" 运行时错误或 "variable might not be initialized" 的警告警告。该库已经用几种不同类型的数据结构(其中一些大到 15kB)进行了测试,数据完整性和性能令人满意。
知道为什么我会收到这些警告吗?
非常感谢,祝好!
C 中的通用指针类型是 void*
。然而,没有通用的指针到指针类型 void**
。所以强制转换 (void**)&shm_area
是不兼容指针类型之间的强制转换。从技术上讲,这是未定义的行为(严格的别名违规),所以任何事情都有可能发生。
要解决此问题,请使用临时 void*
作为参数传递:
void* vptr = shm_area;
LayOutShm(...&vptr);
shm_area = vptr;