Come posso fare le chiamate di sistema invocano mio gestore SIGSEGV quando somministrato memoria protetta?

StackOverflow https://stackoverflow.com/questions/1071860

Domanda

Sto lavorando a una memoria di tracciamento libreria dove usiamo mprotect per rimuovere l'accesso alla maggior parte della memoria di un programma e un gestore SIGSEGV per ripristinare l'accesso alle singole pagine come il programma li tocca. Questa grande opera la maggior parte del tempo.

Il mio problema è che quando il programma invoca una chiamata di sistema (ad esempio read) con la memoria che la mia biblioteca ha segnato nessun accesso, la chiamata di sistema semplicemente restituisce -1 e imposta errno a EFAULT. Questo cambia il comportamento dei programmi in fase di sperimentazione in modo strano. Vorrei essere in grado di ripristinare l'accesso ad ogni pagina di memoria dato a una chiamata di sistema prima che in realtà va al kernel.

Il mio approccio attuale è quello di creare un wrapper per ogni chiamata di sistema che tocca la memoria. Ogni involucro avrebbe toccato tutta la memoria dato ad essa prima di consegnarlo off per la chiamata di sistema reale. Sembra che questo funziona per le chiamate effettuate direttamente dal programma, ma non per quelle fatte da libc (per esempio, fread chiamerà <=> direttamente senza utilizzare il mio involucro). C'è un approccio migliore? Come è possibile ottenere questo comportamento?

È stato utile?

Soluzione

È possibile utilizzare ptrace(2) per raggiungere questo obiettivo. Esso consente di monitorare un processo e viene detto ogni volta che si verificano determinati eventi. Per i vostri scopi, guarda PTRACE_SYSCALL che permette di fermare il processo all'entrata syscall e di uscita.

Si dovrà modificare alcune della vostra memoria infrastrutture di monitoraggio, tuttavia, come ptrace opera in modo tale che un processo padre controlla un processo figlio, e per quanto il bambino è interessato che non hanno la visibilità di quando un monitorato si verifica un evento. Detto questo, si dovrebbe essere in grado di fare qualcosa sulla falsariga di:

  • Imposta ptrace genitore e figlio, il monitoraggio (almeno) PTRACE_GETREGS.
  • processo bambino lo fa una chiamata di sistema; e genitore viene avvisato.
  • Parent salva informazioni syscall richiesto; e utilizza PTRACE_SETREGS e SIGUSR1 di cambiare lo stato bambino in modo invece di chiamare la chiamata di sistema; il processo figlio chiama la routine 'rimuovere la protezione memoria'.
  • di essa la memoria rimuovere la protezione del bambino; poi solleva SIGUSR o simile a dire il controllo genitore che il lavoro della memoria è completa.
  • catture controllanti <=>, <=> utilizza per ripristinare le informazioni syscall previouly salvato e riprende il bambino.
  • Bambino riprende ed esegue la chiamata di sistema orignal.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top