16 votes

Obtenir autant de mémoire non initialisée que possible

J'essaie de créer un programme C/C++ qui décharge autant de mémoire non initialisée que possible. Le programme doit être exécuté par un utilisateur local, c'est-à-dire en mode utilisateur.

L'utilisation de malloc ne fonctionne pas : Pourquoi malloc initialise-t-il les valeurs à 0 dans gcc ?

L'objectif n'est pas d'utiliser ces données comme une graine de hasard.

Le système d'exploitation veille-t-il toujours à ce que vous ne puissiez pas voir les "restes" d'autres processus ?

Si possible, j'aimerais avoir des références à des mises en œuvre ou des explications supplémentaires.

11voto

Adrian McCarthy Points 17018

Les systèmes d'exploitation multi-utilisateurs les plus courants (Windows moderne, Linux, autres variantes d'Unix, VMS - probablement tous les systèmes d'exploitation avec un concept de mémoire virtuelle) tentent d'isoler les processus les uns des autres pour des raisons de sécurité. Si le processus A pouvait lire la mémoire restante du processus B, il pourrait avoir accès à des données utilisateur qu'il ne devrait pas avoir, c'est pourquoi ces systèmes d'exploitation effacent les pages de mémoire avant qu'elles ne deviennent disponibles pour un nouveau processus. Il faudrait probablement disposer de privilèges élevés pour accéder à la mémoire vive non initialisée, et la solution dépendrait probablement du système d'exploitation utilisé.

Les systèmes d'exploitation intégrés, DOS et les anciennes versions de Windows ne disposent généralement pas des moyens nécessaires pour protéger la mémoire. Mais ils n'ont pas non plus de concept de mémoire virtuelle ou d'isolation forte des processus. Sur ces systèmes, il suffit d'allouer de la mémoire par les méthodes habituelles (par ex, malloc ) vous donnerait de la mémoire non initialisée sans que vous ayez à faire quoi que ce soit de spécial.

Pour plus d'informations sur Windows, vous pouvez rechercher Windows zero page thread pour en savoir plus sur le thread du système d'exploitation dont la seule tâche est d'écrire des zéros dans les pages inutilisées afin qu'elles puissent être redistribuées. Windows dispose également d'une fonction appelée superfetch qui remplit la mémoire vive inutilisée avec des fichiers que Windows prévoit d'ouvrir bientôt. Si vous allouez de la mémoire et que Windows décide de vous donner une page superfetch, vous risquez de voir le contenu d'un fichier que vous n'avez pas le droit de lire. C'est une autre raison pour laquelle les pages doivent être effacées avant d'être allouées à un processus.

6voto

R.. Points 93718

Vous avez une mémoire non initialisée. Elle contient des valeurs indéterminées. Dans votre cas, ces valeurs sont toutes égales à 0. Rien d'inattendu. Si vous voulez des nombres pseudo-aléatoires, utilisez un PRNG. Si vous voulez de vrais nombres aléatoires ou de l'entropie, utilisez une source aléatoire légitime comme le périphérique de nombres aléatoires de votre système d'exploitation (par ex. /dev/urandom ) ou API.

3voto

user3344003 Points 3070

Aucun système d'exploitation sain d'esprit ne fournira de mémoire non initialisée à un processus.

Ce qui s'en rapproche le plus, c'est la pile. Cette mémoire aura été initialisée lors de la mise en correspondance avec le processus, mais une grande partie aura été écrasée.

2voto

Art Points 6040

C'est une question de bon sens. Nous n'avons pas non plus besoin de documenter le fait que 1+1=2.

Un système d'exploitation qui laisse échapper des secrets entre les processus serait inutile pour de nombreuses applications. Par conséquent, si un système d'exploitation à usage général veut l'être, il isolera les processus. Garder la trace des pages qui pourraient contenir des secrets et de celles qui sont sûres représenterait une charge de travail trop importante et une source d'erreurs trop importante, c'est pourquoi nous supposons que chaque page qui a été utilisée est sale et contient des secrets. L'initialisation de nouvelles pages avec des déchets est plus lente que l'initialisation avec une seule valeur, c'est pourquoi les déchets aléatoires ne sont pas utilisés. La valeur la plus utile est zéro (pour calloc ou bss par exemple), de sorte que les nouvelles pages sont mises à zéro pour les effacer.

Il n'y a pas d'autre solution.

Il peut y avoir des systèmes d'exploitation spéciaux qui ne le font pas et qui laissent filtrer des secrets entre les processus (cela peut être nécessaire pour des exigences de temps réel, par exemple). Certains systèmes d'exploitation plus anciens ne disposaient pas d'une gestion de la mémoire et d'une isolation des privilèges décentes. En outre, malloc réutilisera la mémoire précédemment libérée au sein du même processus. C'est pourquoi malloc sera documenté comme contenant des déchets non initialisés. Mais cela ne signifie pas que vous serez jamais en mesure d'obtenir de la mémoire non initialisée d'un autre processus sur un système d'exploitation général.

Je suppose qu'une règle simple est la suivante : si votre système d'exploitation vous demande un jour un mot de passe, il ne donnera pas de pages non initialisées à un processus et, puisque la mise à zéro est le seul moyen raisonnable d'initialiser les pages, elles seront mises à zéro.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X