ProgrammationDéveloppeur Backend C

Comment réaliser une copie de mémoire sécurisée entre des tableaux en C ? Quelles fonctions de la bibliothèque standard utiliser et quelles sont leurs différences ?

Réussissez les entretiens avec l'assistant IA Hintsage

Réponse

Historique de la question

La copie de mémoire sécurisée est l'une des tâches les plus courantes et critiques en C. Initialement, les programmes utilisaient une boucle pour effectuer une copie octet par octet. Plus tard, des fonctions standard ont été ajoutées : memcpy, memmove, ainsi que des alternatives plus sûres comme strncpy pour les chaînes. Une mauvaise copie peut entraîner des débordements de mémoire tampon et des vulnérabilités.

Problème

L'utilisation d'une fonction inappropriée ou d'une taille incorrecte lors de la copie peut corrompre les données ou même ouvrir des possibilités aux personnes malveillantes. Faire la distinction entre les cas où memmove doit être utilisé et ceux où memcpy est acceptable est crucial pour éviter les erreurs avec des zones de mémoire qui se chevauchent.

Solution

Pour une copie sécurisée de mémoire non textuelle, utilisez :

memcpy(dest, src, n);
  • memcpy copie rapidement n octets de src vers dest, à condition que leurs zones de mémoire ne se chevauchent pas.
  • Si les zones peuvent se chevaucher, utilisez memmove :
memmove(dest, src, n);

Pour copier des chaînes, utilisez soit strncpy, soit, de préférence, des alternatives modernes et sécurisées, si elles sont disponibles (strlcpy).

Caractéristiques clés :

  • memcpy est sécurisé uniquement en l'absence de chevauchement entre src et dest.
  • memmove fonctionne correctement même avec des zones de mémoire se chevauchant.
  • Pour les chaînes, il est préférable d'utiliser des fonctions spécialisées, en tenant compte du caractère nul terminal.

Questions pièges.

1. Quelle est la différence entre memcpy et memmove et quand l'une ou l'autre fonction est-elle nécessaire ?

memcpy fonctionne très rapidement, mais n'est pas destiné aux zones de mémoire chevauchantes - le résultat sera imprévisible. memmove garantit une copie correcte, peu importe le chevauchement :

int arr[] = {1,2,3,4,5}; // memmove : copie sécurisée avec chevauchement memmove(arr+1, arr, 4 * sizeof(int));

2. Est-il sûr d'utiliser strcpy pour copier une chaîne dans un tampon plus petit ?

Non, la fonction strcpy ne vérifie pas la taille du tampon de destination. Cela entraîne souvent un débordement de mémoire tampon. Il est préférable d'utiliser strncpy, ou strlcpy (si disponible), ou de contrôler explicitement la taille :

char dest[5]; strncpy(dest, src, sizeof(dest)-1); // src doit être plus court que 5 caractères

3. Peut-on utiliser memcpy pour copier des structures avec des pointeurs ?

Oui, mais cela ne copie que les pointeurs eux-mêmes, et non les données aux adresses concernées. Cela peut entraîner des erreurs lors de l'utilisation de la mémoire et des libérations doubles.

Erreurs typiques et anti-modèles

  • Utilisation de memcpy lors de chevauchement de zones de mémoire.
  • Ignorer la taille du tampon de destination.
  • Copier des structures contenant des pointeurs avec un simple memcpy (copie superficielle).

Exemple de la vie réelle

Cas négatif

Une longue chaîne est copiée dans un petit tampon à l'aide de strcpy sans vérifier la longueur de la source. Cela entraîne un débordement de mémoire tampon, menant à une vulnérabilité.

Avantages :

  • Code minimal, exécution rapide.

Inconvénients :

  • Vulnérabilités de sécurité, plantages possibles, corruption de mémoire.

Cas positif

On utilise strncpy ou memmove avec un contrôle précis de la taille, en garantissant manuellement le caractère nul terminal de la chaîne.

Avantages :

  • Comportement prévisible, protection contre le débordement de mémoire tampon.

Inconvénients :

  • Nécessite un contrôle supplémentaire de la longueur et, éventuellement, une légère diminution de la vitesse en raison des vérifications supplémentaires.