gpt4 book ai didi

c++ - mprotect 和文件句柄

转载 作者:太空宇宙 更新时间:2023-11-04 09:39:09 24 4
gpt4 key购买 nike

我有一个简单的程序,我试图保护一 block 内存,然后将一个文件读入该内存,并在出现段错误时释放它。一开始我以为只有文件是 fifo 才有问题。但现在看来,即使是普通文件,它也会失败,

这是代码:

#include <errno.h>
#include <string.h>
#include <iostream>
#include <assert.h>
#include <malloc.h>
#include <sys/mman.h>
#include <unistd.h>
#include <map>
#include <algorithm>
#include <unistd.h>
#include <signal.h>
using namespace std;

#define BUFFER_SIZE 8000
#define handle_error(msg) \
do { cout << __LINE__ << endl ;perror(msg); exit(EXIT_FAILURE); } while (0)

volatile int fault_count = 0;
char* buffer = 0;
int size = 40960;

int my_fault_handler(void* addr, int serious) {
if (mprotect(buffer, size,
PROT_READ | PROT_WRITE) == -1)
handle_error("mprotect");
++fault_count;
cout << "Segfaulting" << endl;
return 1;
}


static void handler(int sig, siginfo_t *si, void *unused) {
my_fault_handler(si ->si_addr, sig);
}
int main (int argc, char *argv[])
{
long pagesize = sysconf(_SC_PAGESIZE);
struct sigaction sa;

sa.sa_flags = SA_SIGINFO | SA_NOCLDWAIT;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = &handler;
if (sigaction(SIGSEGV, &sa, NULL) == -1)
perror("sigaction");

cerr << "pageSize: " << pagesize << endl;

buffer = (char*)memalign(pagesize, size);
if (buffer == NULL)
handle_error("memalign");
if (mprotect(buffer, size, PROT_READ) == -1)
handle_error("mprotect");

FILE* file = fopen("test", "r");
cout << "File Open" << endl;
if (!file) {
cout << "Failed opening file " << strerror(errno) << endl;
return 0;
}

//*buffer = 0;
while(fread(buffer, pagesize*2, 1, file)) {
if (mprotect(buffer, size,
PROT_READ) == -1)
handle_error("mprotect");
}
cout << ' ' << strerror(errno) << endl;

return(0);
}

请注意//*buffer = 0;,如果我取消标记此行,程序将出现段错误并正常工作。有人知道吗?errno 是错误的地址。

谢谢!

更新:似乎在这里问了一个类似的问题: Loading MachineCode From File Into Memory and Executing in C -- mprotect Failing在建议 posix_memalign 的地方,我已经尝试过但没有用。

最佳答案

问题是您没有在短暂读取后检查 FILE 句柄中的错误。

系统会告诉您第一个 fread 失败并且没有触发故障处理程序。

如果您在循环外检查了 ferror(例如马虎):

while(fread(buffer, pagesize*2, 1, file)) {
if (mprotect(buffer, size,
PROT_READ) == -1)
handle_error("mprotect");
}
if (ferror(file) != 0) {
cout << "Error" << endl;
}

为什么失败是底层的read失败了,返回了14的errno(EFAULT),不完全是记录在这种情况下读取失败时发生(它表示 Buf 指向分配的地址空间之外。)

当相关代码在用户上下文中运行时,您只能相信在 mprotect 情况下会触发信号处理程序,大多数系统 调用将失败并返回 EFAULT 在缓冲区无效或没有正确权限的情况下。

关于c++ - mprotect 和文件句柄,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23238085/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com