我想在我的程序中访问加密的核心存储卷。 我的计划是将解密块设备映射为能够轻松地在文件系统结构中跳转,而无需自己处理加密。
虽然映射大文件就像魅力一样,但我在mmap系统调用中遇到EINVAL错误,如下代码所示:
#include <stddef.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/mman.h>
int main(int argc, char *argv[])
{
int fd = open("/dev/disk2", O_RDONLY); // this works fine
if (fd < 0)
{
perror("Could not open file"); return(-1);
}
int pagesize = getpagesize(); // page size is 4096 on my system
void* address = mmap(NULL, pagesize, PROT_READ, MAP_SHARED | MAP_FILE, fd, 0); // try to map first page
if (address == MAP_FAILED)
{
perror("Could not mmap"); // Error complaining about an invalid argument
}
}
该设备的大小为112 GB,我在小牛10.9.3上为x86_64编译clang mmap.c -O0 -o mmap
。我的系统有4 GB的RAM和&gt; 10 GB的可用硬盘空间。
man-Page mmap(2)仅列出了EINVAL错误的以下解释,但这些似乎不适用:
- 指定了MAP_FIXED, addr 参数未页对齐,或者所需地址空间的一部分位于用户进程的有效地址空间之外。
- 标记不包含MAP_PRIVATE或MAP_SHARED。
- len 参数为否定。
- 偏移量参数未根据 getpagesize(3 )返回的页面大小进行页面对齐。
[...]
- 标志参数必须指定MAP_PRIVATE或MAP_SHARED。
- 尺寸参数不得为0.
- off 参数必须是pagesize的倍数,由 sysconf ()返回。
虽然我还没有弄清楚实现的所有细节,但是对这个XNU内核源文件的评论明确提到能够映射块设备(只要它共享):{{3 }}
我错过了什么?
答案 0 :(得分:1)
您的问题可能是使用MAP_FILE,因为这表示常规文件而不是块设备。
如果这不起作用,请在打开文件并检查文件长度后尝试调用fstat()。当我使用stat -x获取有关我的系统上的块设备的信息时,文件大小报告为零(ls -l报告大小为&#34; 1,&#34;)。零长度文件也可能阻止您创建映射。