Pourquoi strncpy n’est pas sûr?

Je cherche à savoir pourquoi strncpy est considéré comme peu sûr. Quelqu’un at-il une sorte de documentation sur ceci ou des exemples d’exploits l’utilisant?

Regardez ce site . c’est une explication assez détaillée. En gros, strncpy() ne nécessite pas de terminaison NUL, et est donc susceptible de subir de nombreux exploits.

Le problème initial est évidemment que strcpy (3) n’était pas une opération sécurisée , un attaquant pouvant fournir une chaîne plus longue que le tampon qui écraserait le code de la stack et, s’il était soigneusement organisé, pourrait exécuter du code arbitraire de la part de l’attaquant.

Mais strncpy (3) a un autre problème: il ne fournit pas de résiliation nulle dans chaque cas à la destination. (Imaginez une chaîne source plus longue que le tampon de destination.) Les opérations futures peuvent attendre des chaînes conformes à C-terminées entre des tampons de taille égale et un dysfonctionnement en aval lorsque le résultat est copié dans un troisième tampon.

Utiliser strncpy (3) est mieux que strcpy (3) mais des choses comme strlcpy (3) sont encore meilleures.

Pour utiliser strncpy en toute sécurité, vous devez soit (1) coller manuellement un caractère nul dans le tampon de résultat, (2) savoir que le tampon se termine par un null et passer (length-1) à strncpy, ou (3) savoir que le tampon ne sera jamais copié avec une méthode qui ne liera pas sa longueur à la longueur du tampon.

Il est important de noter que strncpy remplira tout le contenu du tampon au-delà de la chaîne copiée, contrairement aux autres variantes de strcpy dont la longueur est limitée. Cela peut dans certains cas être une perte de performance, mais dans d’autres cas, il s’agit d’un avantage de sécurité. Par exemple, si l’on utilisait strlcpy pour copier “supercalifragilisticexpalidocious” dans un tampon puis pour copier “it”, le tampon contiendrait “it ^ ercalifragilisticexpalidocious ^” (utiliser “^” pour représenter un octet nul). Si le tampon est copié dans un format de taille fixe, les données supplémentaires peuvent y être associées.

La question est basée sur une prémisse “chargée”, ce qui rend la question elle-même invalide.

L’ strncpy est que strncpy n’est pas considéré comme peu sûr et n’a jamais été considéré comme peu sûr. Les seules allégations d’insécurité pouvant être attachées à cette fonction sont les revendications générales d’insécurité générale du modèle de mémoire C et du langage C lui-même. (Mais c’est évidemment un sujet complètement différent).

Dans le domaine du langage C, la croyance erronée en une sorte d’insécurité inhérente à strncpy découle de la tendance largement répandue à utiliser strncpy pour «copier des chaînes en toute sécurité», ce que cette fonction ne fait jamais. Une telle utilisation est en effet très sujette aux erreurs. Mais même si vous placez un signe d’égalité entre «très enclin aux erreurs» et «peu sûr», il s’agit toujours d’un problème d’utilisation (c’est-à-dire d’un problème d’éducation) et non d’un problème de strncpy .

Fondamentalement, on peut dire que le seul problème avec strncpy est une dénomination malheureuse, ce qui fait que les programmeurs débutants supposent qu’ils comprennent ce que fait cette fonction au lieu de lire la spécification. En regardant le nom de la fonction, un programmeur incompétent suppose que strncpy est une “version sûre” de strcpy , alors qu’en réalité ces deux fonctions ne sont absolument pas liées.

La même réclamation peut être faite contre l’opérateur de la division, par exemple. Comme la plupart d’entre vous le savent, l’une des questions les plus fréquemment posées à propos du langage C est la suivante: “Je suppose que 1/2 sera évalué à 0.5 mais que j’ai 0 Pourquoi?” Cependant, nous ne prétendons pas que l’opérateur de la division n’est pas sûr parce que les débutants ont tendance à mal interpréter leur comportement.

Pour un autre exemple, nous n’appelons pas les fonctions de générateur de nombres pseudo-aléatoires «non sécurisées» simplement parce que les programmeurs incompétents sont souvent désagréablement surpris par le fait que leur sortie n’est pas vraiment aléatoire.

C’est exactement comme ça avec la fonction strncpy . Tout comme il faut du temps aux programmeurs débutants pour apprendre ce que font réellement les générateurs de nombres pseudo-aléatoires, il leur faut du temps pour apprendre ce strncpy fait réellement strncpy . Il faut du temps pour apprendre que strncpy est une fonction de conversion , destinée à convertir des chaînes à terminaison zéro en chaînes à largeur fixe . Il faut du temps pour apprendre que strncpy n’a absolument rien à voir avec la “copie de chaîne sécurisée” et ne peut pas être utilisée à cette fin.

Certes, cela prend généralement beaucoup plus de temps pour un étudiant de langue d’apprendre le but de strncpy que de régler les choses avec l’opérateur de la division. Cependant, cela constitue une base pour toute réclamation “d’insécurité” contre strncpy .

PS Le document CERT lié dans la réponse acceptée est dédié à cela exactement: démontrer les insécurités de la fonction incompétente typique de la fonction strncpy tant que version “sûre” de strcpy . Il ne s’agit en aucun cas de prétendre que strncpy lui-même est en quelque sorte peu sûr.

Un path de Git 2.19 (Q3 2018) constate qu’il est trop facile de mal utiliser les fonctions de l’API système telles que strcat() ; strncpy() ; … et interdit ces fonctions dans cette base de code.

Voir commit e488b7a , commit cc8fdae , commit 1b11b64 (24 juillet 2018) et commit c8af66a (26 juil 2018) par Jeff King ( peff ) .
(Fusionné par Junio ​​C Hamano – gitster – dans commit e28daf2 , 15 août 2018)

banned.h : marquer strcat() comme interdit

La fonction strcat() a tous les mêmes problèmes de débordement que strcpy() .
Et en prime, il est facile de se retrouver accidentellement quadratique, car chaque appel suivant doit parcourir la chaîne existante.

Le dernier appel strcat() est parti dans f063d38 (démon: utilisez cld-> env_array lors de la re-création, 2015-09-24, Git 2.7.0).
En général, strcat() peut être remplacé par une chaîne dynamic ( strbuf ou xstrfmt ) ou par xsnprintf si vous savez que la longueur est limitée.

La pire situation se produit lorsque la mémoire tampon de votre source et de votre destination se chevauchent. Donc, évitez d’utiliser strncpy lorsque vous sentez que votre programme peut se chevaucher. Au lieu de strncpy, vous pouvez utiliser la fonction memmove dans le scénario de chevauchement.

Je décris ci-dessous un exemple simple décrivant la strncpy dans le scénario de chevauchement.

  #include  #include  int main() { char aszMessage[10] ="12345"; //Source Buffer short siLen=4; // Length of byte you want to copy strncpy(aszMessage + 2,aszMessage+1,siLen);//Here memory overlap printf("\n\n\tMessage = %s\n",aszMessage); return 0; } 

Ici j’accepte, la sortie devrait être 122345 mais ici la sortie est 122222, qui est le plus grand scénario de repli de strncpy.

Ce problème peut être résolu en utilisant la fonction memove.

  #include  #include  int main() { char aszMessage[10] ="12345"; //Source Buffer short siLen=4; // Length of byte you want to copy memmove(aszMessage + 2,aszMessage+1,siLen);//Here memory overlap printf("\n\n\tMessage = %s\n",aszMessage); return 0; } 

Maintenant, je reçois la sortie désirée 122345.

Pour plus de détails, vous pouvez voir ce lien http://aticleworld.com/how-to-use-strncpy-and-how-to-write-your-own-strncpy/