在linux编写程序的时候,对某对内存进行写操作时,需要确保该内存是可写,否则往里面写的话,就会出现内存写保护段错误,这样程序就崩溃了,所以为了对这个内存地址操作时安全的(即内存是可写的),可以通过下面方法进行检查。


在Linux下面/proc/pid/maps,这个文件里面保存了执行进程的所有内存映射情况以及内存属性,在程序里面可以通过读该文件进行判断内存是否可写。有些人会认为,有必要吗,调用者要确保传入的参数是正确的,听起来也有道理,但在某些场合,就是因为用户传入参数出错,或这个参数被踩了,导致这个函数写内存而崩溃,是不允许的。

 

下面这个函数可以检查输入地址和一个长度,检查这个范围中,是否都可以写。

#include <stdio.h>
#include <unistd.h>

int check_mem_wrtieable(unsigned long addr, int len)
{
	pid_t pid ;
	char access, maps[32] , buff[1024];
	unsigned long start_addr, end_addr, last_addr;
	FILE *fmap;
	
	pid = getpid(); 	 
	sprintf(maps, "/proc/%d/maps", pid); 
	fmap = fopen(maps, "rb");
	if(!fmap){
		printf("open %s file failed!/n", maps);
		return 0;
	} 
	
	while(fgets(buff, sizeof(buff)-1, fmap) != NULL) {
		/* "%*c"表示忽略第一个字符 */
		sscanf(buff, "%lx-%lx %*c%c", &start_addr, &end_addr, &access);
		if((addr >= start_addr) && (addr <= end_addr)){ 
			if('w' != access){
				fclose(fmap);
					return 0;
			}
			
			if((addr + len) < end_addr){
				fclose(fmap);
				return 1; 
			}else {
				last_addr = end_addr;
				len = len - (end_addr - addr);
				addr = last_addr;
			}
		}
	}
	
	fclose(fmap);		
	return 0;
	
}


Logo

更多推荐