/ / Jak mogę wywołać wywołania systemowe do obsługi SIGSEGV, gdy otrzymasz chronioną pamięć? - linux, pamięć, wywołania systemowe, sigsegv

W jaki sposób można wywołać wywołania systemowe, wywołując moją procedurę obsługi SIGSEGV, gdy podano chronioną pamięć? - Linux, pamięć, wywołania systemowe, sigsegv

Pracuję nad biblioteką śledzenia pamięci, w której używamy mprotect aby usunąć dostęp do większości pamięci programu i obsługi SIGSEGV, aby przywrócić dostęp do poszczególnych stron, gdy program ich dotyka. To działa świetnie przez większość czasu.

Moim problemem jest to, że gdy program wywołuje wywołanie systemowe (powiedzmy read) W przypadku pamięci, w której moja biblioteka zaznaczyła brak dostępu, wywołanie systemowe po prostu zwraca -1 i ustawia errno do EFAULT. Zmienia to zachowanie programów testowanych w dziwny sposób. Chciałbym móc przywrócić dostęp do każdej strony pamięci przekazanej do wywołania systemowego, zanim rzeczywiście trafi do jądra.

Moje obecne podejście polega na stworzeniu opakowania dlakażde wywołanie systemowe, które dotyka pamięci. Każde opakowanie dotknęłoby całej podanej pamięci przed przekazaniem go do rzeczywistego wywołania systemowego. Wygląda na to, że będzie działać dla połączeń wykonywanych bezpośrednio z programu, ale nie dla połączeń wykonywanych przez libc (na przykład, fread zadzwonię read bezpośrednio bez używania mojego opakowania). Czy jest jakieś lepsze podejście? Jak można uzyskać takie zachowanie?

Odpowiedzi:

5 dla odpowiedzi № 1

Możesz użyć ptrace(2) osiągnąć to. Umożliwia monitorowanie procesu i otrzymywanie informacji o wystąpieniu określonych zdarzeń. Dla swoich celów spójrz na PTRACE_SYSCALL co pozwala zatrzymać proces po wejściu i wyjściu z systemu.

Musisz jednak zmienić część swojej infrastruktury śledzenia pamięci ptrace działa tak, że proces nadrzędny monitoruje aproces potomny, a jeśli chodzi o dziecko, nie ma widoczności, kiedy występuje zdarzenie monitorowane. Powiedziawszy to, powinieneś być w stanie zrobić coś na wzór:

  • Instalator śledzi rodzica i dziecko, monitoruje (przynajmniej) PTRACE_SYSCALL.
  • Proces potomny wykonuje wywołanie systemowe; a rodzic zostanie powiadomiony.
  • Parent zapisuje żądaną informację o wywołaniu systemu; i używa PTRACE_GETREGS i PTRACE_SETREGS aby zmienić stan dziecka, zamiast wywoływać wywołanie systemowe; proces potomny wywołuje procedurę „zabezpieczyć pamięć”.
  • Dziecko chroni pamięć „s”; potem podnosi SIGUSR1 lub podobny, aby powiedzieć kontrolującemu rodzicowi, że praca pamięci jest zakończona.
  • Połowy rodziców SIGUSR, używa PTRACE_SETREGS przywrócić poprzednio zapisane informacje o wywołaniu i wznowić dziecko.
  • Dziecko wznawia i wykonuje wywołanie systemowe.