Je me demande s'il existe un moyen d'écrire-protéger chaque page dans un espace d'adressage de processus de Linux (de l'intérieur du processus lui-même, par l'intermédiaire de mprotect()
). Par "chaque page", je veux dire vraiment toutes les pages de l'espace adresse du processus qui pourrait être écrit par un programme ordinaire fonctionnant en mode utilisateur - donc, le texte du programme, les constantes, les globals, et le tas - - mais je serais heureux avec juste des constantes, globals, et tas. Je ne veux pas écrire-protéger la pile - que semble être une mauvaise idée.Puis-je protéger en écriture chaque page de l'espace d'adressage d'un processus Linux?
Un problème est que je ne sais pas par où commencer à protéger en écriture la mémoire . En regardant /proc/pid/maps
, qui montre les sections de la mémoire en cours d'utilisation pour un pid donné, ils semblent toujours commencer par l'adresse 0x08048000
, avec le texte du programme. (Dans Linux, pour autant que je peux dire, la mémoire d'un processus est présentée avec le texte du programme au fond , puis les constantes ci-dessus, puis globales, puis le tas, puis un espace vide de taille variable en fonction sur la taille de la pile tas ou , puis la pile qui descend du haut de la mémoire à adresse virtuelle 0xffffffff
.) Il y a un moyen de dire où est le sommet de le tas (en appelant sbrk(0)
, qui renvoie simplement un pointeur vers le "pause" actuelle, à savoir, le sommet du tas), mais pas vraiment un moyen de dire où le tas commence.
Si j'essaie de protéger toutes les pages de 0x08048000
jusqu'à la coupure, I finit par obtenir une erreur mprotect: Cannot allocate memory
. Je ne sais pas pourquoi mprotect
serait allouer de la mémoire de toute façon - et Google n'est pas très utile. Des idées?
Par ailleurs, la raison pour laquelle je veux faire est parce que je veux créer une liste de toutes les pages qui sont écrites au cours d'une exécution du programme, et la manière que je peux penser à faire est d'écrire-protéger toutes les pages, laisser toute tentative d'écriture provoque une faute d'écriture, puis implémenter un gestionnaire d'erreur d'écriture qui va ajouter la page à la liste, puis supprimer la protection d'écriture . Je pense que je sais comment implémenter le gestionnaire, si seulement je pouvais déterminer quelles pages protéger et comment le faire.
Merci!
En fait, j'ai déjà du code qui fait exactement ce que vous essayez de faire. Votre idée fonctionnera, mais vous ne pourrez pas protéger les pages sur lesquelles résideront vos listes "ces pages" ou votre SEGV provoquera un SEGV! – Borealid
@Borealid, merci, et c'est maintenant le problème que j'essaie de résoudre (j'ai le gestionnaire de segfault et l'analyse de/proc/self/maps qui fonctionne maintenant). Comment éviter de protéger les pages qui contiennent cette liste? Allouer la liste sur la pile fonctionnerait, mais je ne vois aucun moyen de le passer au gestionnaire. Sinon, je pourrais l'allouer globalement, mais j'aimerais utiliser une structure de données plus sophistiquée qu'un tableau de taille fixe (comme un conteneur STL), et je ne saurais pas toujours où se trouve la liste à laquelle j'écris. en mémoire. –
@borealid: Vous avez dit que vous avez du code qui fait exactement cela - cela vous dérangerait-il de partager votre code? Je suis nouveau ici, et je n'ai pas trouvé de moyen de vous contacter directement (back-channel). J'essaie de faire exactement ce que fait Linsey, donc tous les exemples de code seraient très utiles. –