でセグメンテーションフォールトを起こししようとすると、私はmmap
でカーネルからいくつかのメモリを割り当てるしようとしているとは、それは私が欲しいの後に任意のメモリアクセスは、セグメンテーションフォールトを引き起こすように保護ビットを設定しましたセグメンテーションフォールトが再び発生しないように保護ビットを設定しようとする。ただ、物事の仕組みを理解することはmmap
sigaction
のためのLinuxのmanページがsiginfo
構造体のsi_addr
機能に障害が発生したアドレスが含まれていることを述べているにもかかわらず、MPROTECTへの呼び出しは失敗し、si_addr
のアドレスが間違っています。アドレスはmain()
関数で割り当てられたアドレスではありません。 コードMAC
#define _XOPEN_SOURCE
#include <iostream>
#include <signal.h>
#include <ucontext.h>
#include <sys/mman.h>
#include <string.h>
#include <cstdlib>
using std::cout;
using std::cerr;
using std::endl;
void handle_signal(int signal_number, siginfo_t* signal_info, void* context);
void register_signal_handler();
int counter = 0;
int main() {
register_signal_handler();
int* page_mapped = (int*) mmap(nullptr, 100, PROT_NONE,
MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (page_mapped == MAP_FAILED) {
cerr << "mmap failed" << endl;
}
cout << "page mapped is " << reinterpret_cast<uintptr_t>(page_mapped)
<< endl;
// cause the segmentation fault
cout << *page_mapped << endl;
return 0;
}
void handle_signal(int, siginfo_t* siginfo, void*) {
cout << "Handled a segmentation fault" << endl;
cout << "The segmentation fault was caused by the address "
<< reinterpret_cast<uintptr_t>(siginfo->si_addr) << endl;
if (mprotect(siginfo->si_addr, 100, PROT_READ | PROT_WRITE) == -1) {
cerr << "mprotect failed" << endl;
exit(1);
}
// stop an infinite loop
++counter;
if (counter == 3) {
cerr << "Counter got to 3, probably going into an infinite loop.. "
"stopping" << endl;
exit(1);
}
}
void register_signal_handler() {
struct sigaction sigaction_information;
memset(&sigaction_information, 0, sizeof(struct sigaction));
sigaction_information.sa_sigaction = &handle_signal;
sigaction(SIGSEGV, &sigaction_information, nullptr);
}
* SIGSEGVシグナルハンドラは、シグナルハンドラがセグメンテーション違反を引き起こしたページからの保護を削除し(したがって、同じマシン命令を再起動しても同じ信号をリレイズべきではない)場合は、なぜこれが必要である*マシンの状態を変更する必要がありますか? – Leon
保護を変更すると、マシンの状態が変更されます(例:MMUで)。 –
したがって、セグメンテーションフォルトの原因となったアドレスを適切に保護するためにmprotectを取得するにはどうすればよいですか? – Curious