mprotect и файловые дескрипторы

У меня есть эта простая программа, в которой я пытаюсь защитить блок памяти, а затем считывать файл в эту память, освобождая его, когда происходит ошибка.
Сначала я думал, что проблема была только в том случае, если файл 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 ;, если я снимаю метку с этой строки, программа segfaults и работает правильно ..
У кого-нибудь есть идеи?
ошибочный адрес.

Спасибо!

ОБНОВИТЬ:
Кажется, что подобный вопрос был задан здесь:
Загрузка MachineCode из файла в память и выполнение в C — mprotect Failing
где было предложено posix_memalign, я попробовал это, и это не сработало.

0

Решение

Проблема в том, что вы не проверяете ошибку в FILE обрабатывать после короткого чтения.

Система скажет вам, что первый хэнд потерпел неудачу а также не вызывал обработчик ошибок.

Если вы проверили для 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 (EFAULT), что не совсем то, что задокументировано, когда происходит сбой чтения в этой ситуации (это говорит о том, что Buf points outside the allocated address space.)

Вы можете доверять обработчику сигналов только в случае mprotect, когда рассматриваемый код выполняется в пользовательском контексте, большинство система звонки не удастся и вернется EFAULT в случае, если буфер недействителен или не имеет правильных разрешений.

2

Другие решения


По вопросам рекламы [email protected]