12
votes

Solution MAC pour «Safe» Alternatives aux fonctions de bibliothèque standard «dangereuses» C / C ++?

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.

De nombreuses fonctions de bibliothèque de la norme C (par exemple, vfprintf ) sont considérées comme dangereuses en raison du potentiel de débordement tampon ou d'autres problèmes de sécurité.

sous Windows, les compilateurs Microsoft C / C ++ fournissent le " _s "Fonctions (par exemple, vfprintf_s ) 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.

Apple (ou une tierce partie) fournit-il quelque chose de similaire à utiliser avec GCC sur OSX?

En particulier, je recherche des implémentations "sûres" de au moins les fonctions suivantes:

fopen vfprintf vsprintf sprintf strncpy strcpy strcat

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.


11 commentaires

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" - 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" - 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 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.


8 Réponses :


5
votes

à la place Sprintf et VSPrintf, vous souhaitez utiliser:

strlcpy(dest, src, dest_size);
strlcat(dest, src, dest_size);


1 commentaires

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 () et al. Autant est dangereux - mais le reste n'est pas.



3
votes

Étant donné que l'UseLland d'OSX est basée sur FreeBSD , vous do ont des fonctions plus agréables Comme strlcpy et strlcat .


0 commentaires

16
votes

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


6 commentaires

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.



3
votes

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


3 commentaires

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. [...]



4
votes

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 vsnprintf_s () . 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.

Par exemple, TR 24731-1 indique l'interface à VSNPRINTF_S () est: xxx

malheureusement, MSDN dit l'interface à vsnprintf_s () est: xxx

paramètres

  • Tampon - Emplacement de stockage pour la sortie.
  • Sizeofbuffer - la taille du tampon pour la sortie.
  • Compte - Nombre maximum de caractères à écrire (non compris la null de terminaison) ou _trunate.
  • Format - Spécification au format.
  • argptr - pointeur à la liste des arguments.

    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).


3 commentaires

@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 $' ) 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.



10
votes

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)


0 commentaires

1
votes

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>


0 commentaires

3
votes

En particulier, je cherche des implémentations "sûres" d'au moins les fonctions suivantes: fopen vfprintf vsprintf sprintf strncpy strcpy strcat ...

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é.

C'est facile. Checkout the Guide de codage sécurisé Apple . Apple utilise les fonctions "plus sûres" BSD.

Entrez la description de l'image ici


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.

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 ...


4 commentaires

@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é.