Existe-t-il un meilleur moyen que d'analyser / proc / self / maps pour comprendre la protection de la mémoire?

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

Question

Sous Linux (ou Solaris), existe-t-il un meilleur moyen que d'analyser manuellement / proc / self / maps pour déterminer si vous pouvez ou non lire, écrire ou exécuter tout ce qui est stocké chez plus d'adresses en mémoire?

Par exemple, sous Windows, vous avez VirtualQuery .

Sous Linux, je peux mprotect pour modifier ces valeurs, mais je ne peux pas les relire.

De plus, existe-t-il un moyen de savoir quand ces autorisations changent (par exemple, lorsqu'une personne utilise mmap sur un fichier derrière mon dos), mis à part faire quelque chose de terriblement envahissant et d'utiliser ptrace sur tous les threads du processus et interceptant toute tentative de passer un appel système pouvant affecter la carte mémoire?

Mise à jour:

Malheureusement, je l’utilise dans un JIT qui contient très peu d’informations sur le code qu’il exécute pour obtenir une approximation de ce qui est constant. Oui, je me rends compte que je pourrais avoir une carte constante de données mutables, comme la page vsyscall utilisée par Linux. Je peux revenir en toute sécurité sur l'hypothèse que tout ce qui n'est pas inclus dans l'analyse initiale est modifiable et dangereux, mais je ne suis pas entièrement satisfait de cette option.

Actuellement, je lis / proc / self / maps et construis une structure dans laquelle je peux effectuer une recherche binaire pour la protection d'une adresse donnée. Chaque fois que j'ai besoin de savoir quelque chose sur une page qui ne se trouve pas dans ma structure, je relis / proc / self / maps en supposant qu'elle a été ajoutée entre-temps, sinon je serais sur le point de faire une erreur de segmentation de toute façon.

Il semble simplement que l'analyse de texte pour obtenir cette information sans savoir quand elle change est extrêmement cruelle. ( / dev / inotify ne fonctionne pratiquement pas dans / proc )

Était-ce utile?

La solution

Je ne connais pas d'équivalent de VirtualQuery sous Linux. Mais il existe d’autres moyens de le faire qui peuvent ou non fonctionner:

  • vous configurez un gestionnaire de signal piégeant SIGBUS / SIGSEGV et poursuivez votre lecture ou votre écriture. Si la mémoire est protégée, votre code d'interception de signal sera appelé. Sinon, votre code d'interception de signal n'est pas appelé. De toute façon, vous gagnez.

  • vous pouvez suivre chaque fois que vous appelez mprotect et créer une structure de données correspondante qui vous aide à savoir si une région est protégée en lecture ou en écriture. C'est bien si vous avez accès à tout le code qui utilise mprotect .

  • vous pouvez surveiller tous les appels mprotect de votre processus en liant votre code à une bibliothèque redéfinissant la fonction mprotect . Vous pouvez ensuite créer la structure de données nécessaire pour savoir si une région est protégée en lecture ou en écriture, puis appeler le système mprotect pour définir réellement la protection.

  • vous pouvez essayer d'utiliser / dev / inotify et surveiller le fichier / proc / self / maps pour tout changement. Je suppose que celui-ci ne fonctionne pas, mais devrait en valoir la peine.

Autres conseils

Il y a en quelque sorte / was / proc / [pid | self] / pagemap, de la documentation dans le noyau, mises en garde ici: https://lkml.org/lkml/2015/7/14/477 Donc, ce n'est pas complètement inoffensif ...

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top