Quelle est la meilleure solution de bibliothèque C Safe-Shop "Safe" sur le Mac? J'utilise des citations sur "Safe" / "dangereux" car il y a beaucoup de débat quant aux avantages de certaines fonctions de bibliothèque standard ou de leurs alternatives à putain amélioration. P>
De nombreuses fonctions de bibliothèque de la norme C (par exemple, sous Windows, les compilateurs Microsoft C / C ++ fournissent le " _s "Fonctions (par exemple, Apple (ou une tierce partie) fournit-il quelque chose de similaire à utiliser avec GCC sur OSX? P>
En particulier, je recherche des implémentations "sûres" de au moins em> les fonctions suivantes: p>
Veuillez noter: cette question concerne le Mac. Je ne demande pas vos opinions sur la mise en œuvre de Microsoft (à moins que ce ne soit disponible sur le Mac.) Bien que certaines de ces fonctions puissent être faciles à écrire, tout n'est pas tous. Je ne demande pas comment écrire moi-même. Je ne demande pas de conseils sur la façon d'utiliser des classes STL pour le faire. Je ne demande pas comment éteindre les avertissements. Mes besoins particuliers sont très spécifiques. J'essaie d'identifier une API Mac à la meilleure pratique qui est aussi semblable que possible à l'appels de la bibliothèque C traditionnelle C tout en ajoutant de la sécurité. Bien sûr, une implémentation portable qui fonctionne sur Mac et Windows (et d'autres systèmes d'exploitation) serait encore meilleure. Em> p> vfprintf code>) sont considérées comme dangereuses en raison du potentiel de débordement tampon ou d'autres problèmes de sécurité. P>
vfprintf_s code>) comme une alternative plus sûre aux appels de bibliothèque standard. Ces fonctions ne sont pas des remplacements rentrés car ils ont les différentes signatures nécessaires pour fournir des informations de sécurité supplémentaires (par exemple, la longueur de la mémoire tampon). Ils fournissent également d'autres fonctionnalités telles que la détection de chaîne de format non valide, la sécurité de fichier différente, etc. Autant que je sache, cette implémentation n'est pas disponible sur le Mac. P>
fopen vfprintf vsprintf sprintf strncpy strcpy strcat code> p>
8 Réponses :
à la place Sprintf et VSPrintf, vous souhaitez utiliser:
strlcpy(dest, src, dest_size); strlcat(dest, src, dest_size);
VFPRINTF () est dangereux car il soutient la directive «% N» (pour signaler le nombre d'octets écrits au moment où la directive est traitée). C'était un processus drôle (mauvais?) Sur le processus de normalisation C89 - il nécessite un paramètre de sortie (pointeur à int) dans printf () code> et al. Autant est dangereux - mais le reste n'est pas.
Étant donné que l'UseLland d'OSX est basée sur FreeBSD , vous do em> ont des fonctions plus agréables Comme strlcpy et strlcat . p>
Tout d'abord, imprimez la documentation sur les fonctions "sûres / dangereuses" à partir de MSDN et de la gravure!
fopen p>
est aussi sûr que fopen_s ... uless tu es idiot et suppose que cela est retourné Le pointeur n'est pas nul ou fournit NULL comme paramètre d'entrée. P>
strcpy strcat
Strncpy / Strncat sont en sécurité mais sont une douleur à utiliser correctement. Strncpy nécessite que l'appelant ajoutez le terminateur 0. Strncat nécessite que l'utilisateur calculille combien de copier, pas la taille du tampon de destination.
Notez que Microsoft's VSNPRINTF () ne peut pas être compatible standard (C99) car la définition C99 nécessite que VSNPRINTF () ajoutez une null de terminaison à moins que la longueur du tampon ne soit nulle (et qui a une signification particulière). Je suppose que la SP sait ce que cela signifie quand il est dit que son VSNPRINTF () n'ajoute pas toujours le terminal NULL, mais cela signifie simplement que la SP (probablement) la mise en œuvre avant que la norme a canonisé le comportement correct, puis se sentait incapable de risquer de changer le changement de Définition erronée (même s'il est difficile de voir tout code de travail rompre à la suite du changement).
@Artyom, merci pour votre réponse. Vous pouvez supposer en toute sécurité que je suis un idiot. En particulier, vous pouvez parier que je vais éventuellement vous trommer avec une fonction "sûre si je lisais le manuel".
@JWFEARN - Le point est que MS a créé ses propres fonctions «sûres» au lieu d'adopter des fonctions sûres de C99. Par exemple, FOPEN_S est une "merde" totale, Sprintf_S aussi - utilisez SNPRINTF. Etc. Oui, Strncpy et Strncat sont triceux mais toujours, il est beaucoup préférable de rester avec la norme, alors ... Ne vous inquiétez pas tout ce que vous lisez sur "Funtions dangereuses"
En réalité, TR24731 post-dates Les fonctions équivalentes de la MS-MS ont mis en place quelque chose, puis ont soumis leur système au comité Standard C. Ce qui était «standardisé» (dans la mesure où il est normalisé; il s'agit d'un rapport technique pour le moment) était différent de la proposition de la SP.
Strncpy n'est pas sûr. Cela ne garantit pas à NULL-Terminez la chaîne. L'utilisation correctement est une erreur d'erreur.
La norme C a déjà un ensemble de "sécurité" de ces fonctions.
(Pour une définition particulière du terme sûr)
Le SNPRINTF () (et la famille) fournit les fonctions de sécurité que vous recherchez. Vérification du débordement tampon.
En outre, le compilateur de GCC est en outre la validation des chaînes (mais mieux que la SEP, car la validation est effectuée au moment de la compilation). P>
fopen() Not sure how you make that safer? vfprintf -- These are low level functions vsprintf -- These are low level functions sprintf snprintf strncpy Already the safe version strcpy strncpy strcat strncat
Ma compréhension RE: Fopen est que la version "standard" est spécifiée pour utiliser les règles de sécurité par défaut, ce qui peut ne pas correspondre aux défauts "Safe" du système d'exploitation hôte ... ou quelque chose comme ça. Pas que c'est un problème de débordement tampon. Je peux me tromper. Je l'ai inclus dans ma liste car MSVC fournit une fonction FOPEN_S.
Strncpy () doit être utilisé très soigneusement pour être en sécurité - il ne se termine pas lorsque la source est trop longue pour la destination. Il s'agit d'une propriété de rembourrage (nul le remplissage à pleine longueur) est parfois un handicap, surtout si vous avez un tampon de 20 Ko, mais vous êtes surtout des cordes de 50 octets.
@JWFEARN: Dans TR24731, la principale différence entre Fopen () et fopen_s standard () est l'ajout d'un drapeau, 'U'. Citation: dans la mesure où le système sous-jacent prend en charge les concepts, les fichiers ouverts par écrit doivent être ouverts avec un accès exclusif (également appelé non partagé). Si le fichier est en cours de création et que le premier caractère de la chaîne de mode n'est pas «U», dans la mesure où le système sous-jacent prend en charge, le fichier doit avoir une autorisation de fichier qui empêche d'autres utilisateurs du système d'accéder au fichier. [...]
Voir aussi: SO 327980 .
Le Comité C Standard C a créé un rapport technique, TR 24731-1 , en partie à l'encouragement de Microsoft (je crois). Il standardise les interfaces aux différentes fonctions telles que Par exemple, TR 24731-1 indique l'interface à malheureusement, MSDN dit l'interface à paramètres p > Notez que ce n'est pas simplement une question de mappage de type: le nombre d'arguments fixes est différent et donc irréconciliable. Il n'est pas simplement clair pour moi (et vraisemblablement au Comité des normes), quel avantage doit avoir à la fois «zeofbuffer »et« compter »; Il ressemble à la même information deux fois (ou, au moins, du code sera communément écrit avec la même valeur pour les deux paramètres). P> p> vsnprintf_s () code>. Malheureusement, toutefois, l'interface définie par la norme est incompatible avec l'interface définie par Microsoft, rendant ainsi la norme largement non pertinente. P>
VSNPRINTF_S () code> est: p>
vsnprintf_s () code> est: p>
@Jonathan Leffler: Savez-vous si ces API sont disponibles sur le Mac?
Ils ne sont pas dans la bibliothèque principale du système - /usr/lib/libsystem.b.dylib. Je n'ai pas vérifié chaque dylib sur la machine, mais je soupçonne qu'ils sont remarquables par leur absence, ici et sur la plupart des machines à base unique. Quelqu'un a créé la bibliothèque sécurisée pour les routines de chaîne, oh, il y a 6 mois; Vous pourrez peut-être trouver cela sur le Web (demandez-moi si vous ne pouvez pas).
J'ai fait une recherche approfondie ( trouver / -name '* .dylib' -print0 | xargs -0 nm -og -og | grep '_s $' code>) et n'a trouvé aucune des fonctions sécurisées TR 24731 . Il y avait un certain nombre de fonctions qui ont terminé «_s», mais aucune pertinence.
Résumé: Sur Mac, il existe plusieurs options API et compilateur offrant des alternatives plus sûres aux fonctions de la bibliothèque standard. Voici certains d'entre eux par rapport à API "Safe" de Microsoft :
C MSVC PROVIDERS MAC SOLUTION --------------------------------------------------------------------------------- fopen fopen_s C none, assume fopen is safe vfprintf vfprintf_s GCC GCC_WARN_TYPECHECK_CALLS_TO_PRINTF(1) vsprintf vsprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, vsnprintf(2) sprintf sprintf_s GCC, C99 GCC_WARN_TYPECHECK_CALLS_TO_PRINTF, snprintf(3) strncpy strncpy_s BSD strlcpy(4) strcpy strcpy_s BSD strlcpy strcat strcat_s BSD strlcat(5)
Google Summer of Code 2010: Openafs et Google parrainent un port de la bibliothèque de sécurité de String de Microsoft. Voir http://www.openaf.org/pages/gsoc.html . < / p>
En particulier, je cherche des implémentations "sûres" d'au moins les fonctions suivantes: fopen vfprintf vsprintf sprintf strncpy strcpy strcat ... p>
J'essaie d'identifier une API Mac à la meilleure pratique qui est aussi semblable que possible à l'appels de bibliothèque C traditionnels C tout en ajoutant la sécurité. P> blockQuote>
C'est facile. Checkout the Guide de codage sécurisé Apple . Apple utilise les fonctions "plus sûres" BSD. P>
p>
liée: tandis que Apple et Microsoft fournissent des fonctions plus sûres, Linux ne le fait pas. GNU C n'incluait pas les "interfaces de vérification des limites" (ISO TR24731), car les gens comme Ulrich Drepper (un portier GNU Libc) s'est opposé. Il s'est opposé parce que seul le tampon de destination a été spécifié. Il a appelé la fonte BSD "plus sûre". Pour la citation de Drepper, voir Re: Patch: Copie de chaîne sûre et concétation sur la liste de diffusion d'origineware. P>
Après les conseils de Drepper mènera à des échecs spectaculaires. CVE-2012-5958 CVE-2012-5959 CVE-2012-5960 CVE-2012-5961 CVE-2012-5962 CVE-2012-5963 CVE-2012-5963 CVE-2012-5964 CVE-2012-5964 CVE-2012-5965 (également connu sous le nom de plusieurs débordements de tampon à Libupnp) pour la victoire! Son the Bad Bad Libupnp a suivi les meilleures pratiques de Drepper et ignorée et a rejeté les fonctions "plus sûres". Je me demande combien de millions de routeurs et de passerelles restent impressionnés même aujourd'hui ... P>
@JWW: Ces fonctions réellement plus sûres énumérées dans votre image sont fournies sur Linux depuis longtemps. Seule l'annexe dysfonctionnelle K a été ignorée comme superflue et active active.
@DEDUplicator - Hors de curiosité, pourquoi pensez-vous que l'annexe K est dysfonctionnelle? (BTW, c'est maintenant une partie de la norme et n'est plus une annexe).
Jetez un coup d'oeil (encore) à cette question: Stackoverflow.com/Questtions/372980/... et à partir de C11 (qui reste la norme actuelle), ils ne l'ont fait que dans une annexe facultative (qui n'implique pas la mise en œuvre de la SP se conformer). Avant c'était un tr.
@Deduplicateur - Mon mauvais, tu as raison. Ils sont toujours dans une annexe, mais ils sont maintenant normatifs. Apparemment, cela a été le cas depuis 2011 (ISO / CEI 9899: 2011). Mais je suis toujours curieux de la dysfonctionnalité.
L'utilisation de ces fonctions soi-disantes "sûres" n'est pas la meilleure pratique.
Pourquoi ne pouvez-vous pas utiliser les équivalents de la bibliothèque Standard C ++ Standard? (Ou pourquoi le titre dise-t-il la bibliothèque standard C / C ++ si vous refusez d'utiliser la bibliothèque standard C ++)
GCC effectue déjà une vérification de chaîne de format pour les fonctions de bibliothèque standard habituelles C. Il est implémenté à l'aide d'un mot-clé spécial, vous pouvez même le faire avec vos propres fonctions avec des chaînes de format standard.
La norme C a déjà un ensemble de versions «sûres» de ces fonctions. Utilisez la version dans la norme: S__N__PRINTF () et votre famille.
Les fonctions ne sont pas particulièrement faciles à écrire - faire le travail correctement prend des soins et des efforts considérables (je sais; j'ai essayé - et n'a pas fini). Ils ne sont pas terriblement difficiles - juste fidèlement, sans fin avec mobilité réduite. Et le test est difficile aussi.
@Martin York: L'une des bonnes fonctionnalités des fonctions TR24731 '_s' est que les fonctions de formatage ne prennent pas en charge la fonctionnalité '% N' (MIS).
Voir aussi: Stackoverflow.com/questions/372980 - Mais notez que j'ai récemment trouvé, à ma chagrin considérable, que les interfaces MS aux fonctions «_s» ne sont pas les mêmes que les interfaces aux fonctions TR24731. Ainsi, simplement utiliser les fonctions TR24731 n'est pas suffisante ...
@Neil Butterworth: Pourquoi les fonctions "sûres" ne sont-elles pas les meilleures pratiques? Peut-être que vous pourriez citer un lien vers une explication? Quelle est la meilleure pratique sur le Mac?
@Shteef: Merci beaucoup pour votre commentaire. Je vais mordre, quel est le mot clé secret pour activer la vérification de chaîne de format dans GCC? Que diriez-vous d'un lien?
@jwfearn: "Quelle est la meilleure pratique sur le Mac" i> - voir Guide de codage sécurisé Apple . Apple, comme Linux, ne fournit pas TR24731. Apple fournit cependant les alternatives BSD.
@anon: "L'utilisation de ces fonctions soi-disantes" sûres "n'est pas la meilleure pratique" i> - Apple et Microsoft en désaccord avec vous. Drepper arrive à être d'accord avec vous (en supposant qu'il puisse être considéré comme la voix de Linux dans ce cas). Linux a certains des échecs les plus spectaculaires.
libupnp code> pour la victoire (et pour tous ces routeurs non morts): CVE-2012-5958 CVE-2012-5959 CVE-2012-5960 CVE-2012-5960 CVE-2012-5961 CVE-2012-5962 CVE-2012-5962 CVE-2012-5963 CVE-2012-5964 CVE-2012-5965.