Théoriquement, si je construisais un programme qui allouait toute la mémoire inutilisée sur un système et continuait à demander de plus en plus de mémoire alors que d'autres applications libéraient de la mémoire dont elles n'avaient plus besoin, serait-il possible de lire la mémoire récemment libérée d'une autre application ? Ou est-ce en quelque sorte protégé par un système d'exploitation moderne?
Je n'ai aucune application pratique pour cela, je suis juste curieux. Je me rends compte qu'il y a des problèmes avec l'allocation de "toute la mémoire disponible" dans la vie réelle.
Edit: Pour clarifier, je pose des questions spécifiques sur la mémoire «libérée», et non sur l'accès à la mémoire actuellement allouée par une autre application.
la source
The reason you don't always see zeroed out memory is because it is more efficient not to zero out the memory if it was previously allocated by the same process
Je vois une certaine incohérence ici. Voulez-vous dire "même exécutable"? Comment vérifie-t-on s'il ne faut pas mettre à zéro - par le chemin du disque?Plusieurs couches impliquées ici affectent la réponse.
Si vous supposez un système d'exploitation de mémoire virtuelle moderne, vous ne pourrez pas voir les restes des données d'un autre processus dans les pages que vous allouez.
Lorsqu'un processus est chargé pour la première fois, la table de pages est chargée et potentiellement des cadres de mémoire réelle sont alloués à ces pages. Au minimum, la table de pages ou sa table supplémentaire contiendra une carte de toute la mémoire que le processus peut allouer. C'est également là que la pause initiale du processus, mentionnée ci-dessus, est définie.
Alors que malloc () peut, si le processus est autorisé, entraîner une modification de la pause du processus, en ajoutant plus de pages à une table de page de processus (page supplémentaire) pour satisfaire la demande, l'endroit où un processus peut "obtenir un autre" données de processus est à la couche de mémoire réelle inférieure.
Dans ces deux scénarios, un système d'exploitation moderne qui utilise la pagination de la demande ou l'allocation différée n'alloue pas encore de mémoire physique (trames). Le système d'exploitation ne fait que "prendre des notes" sur la mémoire virtuelle de ce processus considérée comme valide. La mémoire réelle n'est attribuée qu'en cas de besoin.
La mémoire physique ou les trames sont allouées à un processus lorsque la page virtuelle est réalisée et mappée dans une table de pages de processus C'est là que le potentiel d'exposition des données existe. Cela se produit lors d'une erreur de page. L'exposition est due au fait qu'un processus précédent utilisait peut-être cette même trame et que ses données ont été abandonnées ou échangées, pour faire de la place pour la demande de mémoire physique actuelle. Le système d'exploitation doit veiller à ce que les données du processus demandeur soient correctement échangées ou que la trame soit effacée (mise à zéro) avant de reprendre le processus. Ceci est également mentionné ci-dessus comme un problème "ancien mais résolu".
Cela rend quelque peu inutile si la mémoire des autres processus a été «libérée» ou non. Un autre processus "libéré" de la mémoire réside toujours dans les pages affectées à ce processus et ne sont généralement pas mappés jusqu'à la fin du processus car ils seront simplement échangés lorsque la mémoire sera faible ou qu'ils seront autrement expulsés. malloc () et free () gèrent la mémoire virtuelle affectée au processus au niveau (utilisateur).
Dans votre question, votre processus, continue de demander de plus en plus de mémoire, en théorie, poussant tous les autres processus hors de la mémoire. En réalité, il existe des stratégies d'allocation de trames - mondiales et locales - qui peuvent également affecter la réponse. Il est tout aussi probable que le processus force ses propres pages à manquer de mémoire avant de pouvoir dépasser le système d'exploitation et tous les autres processus. Bien que cela dépasse votre question initiale.
Tout cela est théorique dans un système comme MS-DOS. MS-DOS (et d'autres systèmes plus simples) n'utilisent pas de mémoire virtuelle (par eux-mêmes) et vous pouvez facilement piquer et produire d'autres données de "processus".
Quelques bonnes références, qui peuvent être plus faciles à comprendre que le code source Linux, seraient un bon manuel de systèmes d'exploitation, Operating Systems Concepts par Silberscatz, Gavin et Gange, ou Operating Systems Design par Andrew Tanenbaum. Quelque chose comme Nachos de Berkeley ou Pintos de Stanford sont de petits systèmes d'exploitation conçus pour l'apprentissage et qui contiennent ces mêmes idées.
la source
J'ai essayé cela sur Ubuntu il y a 16.04 mois. Tout comme 0xACE l'a dit, le système d'exploitation moderne alloue une page virtuelle entièrement nulle une fois que vous avez appelé malloc (). Mais, si vous n'écrivez rien dans le tampon alloué, il ne sera pas mappé dans la mémoire physique (c'est-à-dire le principe de copie sur écriture), ainsi vous lirez toujours les zéros d'un bloc "non initialisé". Il existe peut-être des systèmes d'exploitation intégrés compilés avec l'option "CONFIG_MMAP_ALLOW_UNITIALIZED" pour de meilleures performances, dans ce cas, vous pourriez obtenir ce que vous avez prévu.
la source
Non, cela ne permettra pas à un autre programme de lire la mémoire d'un autre grâce à la magie de la pagination . De cette façon, l'utilisation totale de la mémoire peut dépasser le ram physique en déchargeant des parties de celui-ci sur le disque dur.
De plus, la mémoire maximale qu'un processus peut allouer est arbitrairement limitée par le système d'exploitation (jusqu'à 4 concerts pour une architecture 32 bits), après quoi l'
alloc
appel suivant renverra une erreur de mémoire insuffisante.la source
mlock
).