情况如下:
我正在使用挂钩ioctl()系统调用的LD_PRELOADed模块分析程序与驱动程序的交互。我正在使用的系统(嵌入式Linux 2.6.18内核)幸运地将数据的长度编码到'request'参数中,因此我可以愉快地转储具有正确长度的ioctl数据。
然而,相当多的这些数据都有指向其他结构的指针,我不知道它们的长度(毕竟这是我正在研究的)。所以我正在扫描数据以获取指针,并将数据转储到该位置。我担心如果指针接近段边界,这可能会使我的代码对段错误开放(我的早期测试似乎表明情况就是如此)。
所以我想知道在尝试取消引用之前,我可以做些什么来先发制人地检查当前进程是否拥有特定的偏移量?这甚至可能吗?
编辑:只是一个更新,因为我忘了提到一些非常重要的东西,目标系统是基于MIPS的,虽然我也在我的x86机器上测试我的模块。
答案 0 :(得分:3)
打开/dev/null
的文件描述符并尝试write(null_fd, ptr, size)
。如果在errno
设置为EFAULT
的情况下返回-1,则内存无效。如果它返回size
,则可以安全地读取内存。使用某些POSIX发明可能有更优雅的方式来查询内存有效性/权限,但这是一种经典的简单方法。
答案 1 :(得分:1)
如果你的嵌入式linux安装了/ proc / filesystem,你可以解析/ proc / self / maps文件并验证指针/偏移量。 maps文件包含进程的内存映射,请参阅here
答案 2 :(得分:0)
我知道没有这种可能性。但是你可能能够实现类似的东西。如man 7 signal
所述,SIGSEGV
可以被捕获。因此,我认为你可以
SIGSEGV
SIGSEGV
的处理程序中,标记在步骤2的循环中检查的变量有几个问题。
LD_PRELOAD
电围栏帮助解决这个问题,AFAIK会使应用程序为每个动态分配的缓冲区分配整个页面。所以你不会输出几个缓冲区,认为它只有一个,但是你仍然不知道缓冲区的结束位置,最后会输出很多垃圾。此外,此方法无法帮助基于堆栈的缓冲区。答案 3 :(得分:0)
你不能只检查段边界吗? (我猜是通过分段边界来表示页面边界?)
如果是这样,页面边界被很好地划分(4K或8K),因此地址的简单屏蔽应该处理它。