Il est question de vulnérabilité de code et vous parlez de parsing de syntaxe, vous confondez code source et code exécutable, vous affirmez qu'on peut tout régler en codant bien (sans dire comment)
Le gars qui cherche de bonnes pratiques sur google va tomber sur cette page et se faire engluer dans une discussion dilatoire qui pleine de "moi je", de panpan cucu et de noyages de poissons.
Le moins qu'on puisse dire est qu'il ne va pas trouver d'information utile sur ce topic noyé sous les affirmations péremptoires, jamais prouvées de mecs qui récitent l'info trouvée ailleurs, sans tester quoi que ce soit.
Franchement, à quel moment on parle de buffer overflow ? De cohabitation de variables, arguments et adresses de code dans les appels de fonctions? De pourquoi on ne risque pratiquement rien avec une garbage collection ? des vulnérabilités endémiques du C , des types de strings spécifiques au C++. De comment fonctionne Rust et pourquoi il est plus sûr ?
Qui parle de la nouvelle directive de la DGSI à laquelle nous sommes tous soumis ?
Non, il faut se contenter de "Si le développeur code bien, son code sera sûr !!"
Bon sang, je suis le seul a avoir écrit le mot "String" de toute la conversation.
Développez.net, c'était mieux avant, là c'est de la bouillie
Topic foiré
Personne affirme cela, on dit qu'il y'a 200 UB en C, et qu'il est possible plus facilement de les éviter sur Rust.
Personne ne dit que y'a un langage magique qui résout tout les problèmes.
Pour le moment c'est toi qui fait des affirmations péremptoires, malgré tes années d'expériences ,tu semble au final mal connaître le C , et mal connaître l'asm.
Pas que tu ne sache ni les lire ou les coder, mais que tu n'en comprend pas leur fonctionnement interne (où plutot tu semble interprété leur fonctionnement).
Et je ne vois rien de mal qu'un nouveau venu qui veut apprendre le C, sait qu'il y'a des UB en C, et depuis que je traîne sur les forums et Discord étrangement, c'est les premiers truc qu'il se tape comme erreur.
Il est vrai que cela peut arriver, sur des compilateur un peu ancien
C'est un excellent choix, je code souvent sur du 6502
En gros la discussion à glisser de la sécurité vers les undefined behaviour ou deux visions s'affronte :
- Le pratique : j'ai vérifié sur deux / trois compilos répandu ça me donne le résultat que je pensais
- La standard : tout comportement UB doit être éviter car on ne sait jamais de quoi sera fait le lendemain.
Le plus gros problème c'est l'insistance sur le cas "d'école" qui est juste là pour expliquer l'un des 200 UB existant dans le C. La spécification c'est un contrat, et un UB, c'est un trou dans le contrat ou tu n'as donc aucune garantie, hier, aujourd’hui, demain que ça répond comme tu le penses et comme tu l'as vu. Donc il faut éviter.
De ce que je comprend, le but de faire migrer de C/C++ vers Rust est justement d'obtenir une sécurisation de la mémoire dès la rédaction du code sous un forme compilable (donc la syntaxe) et donc de l'exécutable.Il est question de vulnérabilité de code et vous parlez de parsing de syntaxe, vous confondez code source et code exécutable, vous affirmez qu'on peut tout régler en codant bien (sans dire comment)
Un morceau de code dont la syntaxe est UB selon la spécification est un code qui peut avoir l'air de donner le résultat que tu veux mais pourrait déraper au runtime dans certaines conditions ou en cas de changement d'environnement (compilo, paramètre etc) et donc être exploités comme faille de sécurité potentielle (au sens piratage ici, pas du non crash de l'application).
Après je sais pas à quel point c'est arriver en vrai, j'en ai pas spécialement entendu parler personnellement mais je suit ça d'assez loin via les grand médias ou développez. Pour moi le gros des failles exploitées dont j'ai entendu parler ne sont jusqu'ici pas dû à des exploitations aussi poussé qu'un UB. D'où le fait que ce soit un peu limite dans le sujet de la discussion.
Ça arrive tous les jours, vu que les erreurs de sécurité mémoire, qui sont la principale source d'exploitation, sont une forme de Undefined Behavior.
Après, en effet, il est peu probable de voir un jour d'exploité un i++ + ++i. Déjà parce qu'il doit pas être utilisé tous les jours dans du vrai code, et ensuite car ce genre de code à moins de risque de se voir optimisé de manière dangereuse, que quelque-chose de relatif aux pointeurs.
Après pour obtenir les garanties de sûreté/sécurité du langage Rust en C ou C++, c'est "facile". Il "suffit" de faire en sorte de vérifier que toutes les propriétés garanties par le typage + les vérifications à runtime de Rust sont aussi vérifiées sur un programme qu'on a écrit en C.
Ça se fait, via vérification formelle (genre interprétation abstraite ou vérification déductive). Par contre, on va pas se mentir:
- ça coûte un bras
- bon courage pour trouver un outil qui supporte toutes les fonctionnalités de C
- C++ on va même pas en parler
Bon par contre, en général, on peut aussi vérifier tout un tas de propriétés supplémentaires, mais je ne connais pas beaucoup de boîtes qui ont les reins pour encaisser ça et encore moins dans des contextes non-critiques.
Non, on ne peut pas tout régler en codant bien. Mais il y a des bonnes pratiques et les reconnaître et les utiliser, c'est, me semble-t-il, déjà une bonne chose.
Oui, c'est une pratique très (trop) courante. On peut s'informer sur ce genre de site, mais il faut pas prendre ce qui y est dit pour argent comptant, même si c'est dit par des experts. C'est comme lire un journal quotidien, et prendre pour argent comptent l'information qui s'y trouve. Il faut réfléchir et expérimenter pour valider l'information trouvée. C'est un peu chronophage, et on ne peut pas le faire sur tout et tout le temps, malheureusement. Un exemple, durant la crise covid, ces experts arrivaient avec le même aplomb a dire blanc le lundi et noir le mardi. Tiens ça me fait penser à un Président d'un pays ami :-)Le gars qui cherche de bonnes pratiques sur google va tomber sur cette page et se faire engluer dans une discussion dilatoire qui pleine de "moi je", de panpan cucu et de noyages de poissons.
Le moins qu'on puisse dire est qu'il ne va pas trouver d'information utile sur ce topic noyé sous les affirmations péremptoires, jamais prouvées de mecs qui récitent l'info trouvée ailleurs, sans tester quoi que ce soit.
Oui, on risque moins d'avoir des soucis avec un langage avec GC, mais, malheureusement, ça ne peut pas s'employer partout. C'est notamment le cas dans le monde de l'embarqué, où on a pas le choix. C'est du C ou de l'assembleur. Il y a un compilateur C pour toute les plateformes, je n'ai pas encore trouvé un langage avec GC qui permet de programmer des petits microcontrôleurs. De plus, si on parle de temps réels, il faut s'assurer que le GC ne s'active pas quant il veut. Il n'y pas de une solution magique qui va régler tous les problèmes.Franchement, à quel moment on parle de buffer overflow ? De cohabitation de variables, arguments et adresses de code dans les appels de fonctions? De pourquoi on ne risque pratiquement rien avec une garbage collection ? des vulnérabilités endémiques du C , des types de strings spécifiques au C++. De comment fonctionne Rust et pourquoi il est plus sûr ?
Non, il ne sera pas forcément sûre, mais il sera plus sûre, c'est déjà ça de prit ;-) Le fait de savoir ce que l'on fait, pourquoi on le fait, et comment il faut le faire, c'est aussi un pas dans la bonne direction. Et si on parle de sécurité, prenons l'exemple de Boeing, avec son fameux MAX et son logiciel MSAC qui était sensé pallier à un défaut de construction, on voit le résultat dramatique. Le "software" ne peut pas toujours remédier aux problèmes "hardware". Il faut le reconnaître.Qui parle de la nouvelle directive de la DGSI à laquelle nous sommes tous soumis ?
Non, il faut se contenter de "Si le développeur code bien, son code sera sûr !!"
On est dans une époque où beaucoup de domaines avancent trop vite, et d'autres qui stagnent ou dont on ne se préoccupe pas.
String... Oui, dans certains domaines, encore une fois. Dans d'autres, on ne n'utilise même pas de "string" (le s minuscule est important ;-))Bon sang, je suis le seul a avoir écrit le mot "String" de toute la conversation.
Développez.net, c'était mieux avant, là c'est de la bouillie
Oui, y'a pleins de choses qui étaient mieux avant. Mais il y'a aussi des choses qui sont mieux maintenant. Dans tous les domaines, ont fait de bonnes avancées, et des moins bonnes, sur lesquelles il faut revenir si on constate que finalement, c'était pas une bonne idée. L'IA est une avancée dans certains domaines, et une régression dans d'autres. L'IA n'est pas chose nouvelle, c'est une marotte qui revient périodiquement (jamais comme maintenant), sous d'autres noms, comme la 'logique floue', les systèmes 'experts'. C'est ainsi, l'être humain n'apprend que très doucement a retenir les erreurs du passé. Quand je vois passer des info comme quoi on aura plus besoin de développeurs dans 5 ans, je prend du recul. Le métier évoluera, c'est certains, après tout c'est une discipline assez récente, comparée à l'architecture par exemple. Le développeur qui croit que l'IA va le mettre au rebus, se trompe me semble-t-il. Qui va poser la bonne question à l'IA ? Qui vas pouvoir valider la réponse ? Ce ne sera pas un gars du marketing je pense (y'a rien de mal a faire du marketing, mais c'est pas être développeur, je pense).
Les voitures "autonome" sont un bon exemple. Le jour où on pourra s'y assoir et dire "conduis-moi au travail" et piquer un petit somme durant le trajet n'est pas près d'arriver. Je pense qu'Apple a pris une sage décision en stoppant son programme de voiture "autonome", après y avoir pourtant consacré pas mal de temps et d'énergie. Des "aides à la conduite", oui c'est bien, mais il ne faut pas aller trop loin.
Musk s'y accroche, mais même lui commence a dire qu'il ne pensait pas que ce serait si difficile, voire impossible avec la technologie actuel. Mais comme il a vendu (en mentant ou de bonne fois, je ne sais pas) son autopilote full self driving qui sera là dans 6 mois (et qu'il répétait la même chose depuis 10 ans), il est un peu coincé notre ami Elon, il ne peut pas dire "Je me suis gourré, je vais vous rembourser, car on a pas tenus nos promesses" d'une part à cause de son égo surdimensionné et parce que ce sera la faillite de Tesla en quelques jours.
Un peu, oui, mais on peut apprendre de tout, même des erreurs (des sienne ou de celles des autres). Un monde parfait n'existera jamais, le risque zéro n'existera jamais, et le messie ne reviendra pas nous apporter la même bonne nouvelle et remettre l'humanité sur le droit chemin :-).Topic foiré
Mais pour en revenir à la sécurité/sécurisation du code, le développeur n'est pas le seule responsable. Il est parfois obligé d'utiliser des outils qu'il ne maîtrise pas, pour une politique d'entreprise, parce qu'on lui demande d'aller trop vite, parce que ce qu'on lui demande est tout simplement impossible avec les données qu'il a en entrée via le "hardware" parfois.
Et si on parle de langage "de haut niveau", avec GC, il faut aussi savoir que très souvent, ces langages utilisent simplement des Wrappers autours d'une librairie codée bien souvent codée en C. Plus il y de couches entre un souhait et la réalité, au plus on s'éloigne de cette réalité, pour en finir a désirer des choses qui ne sont pas possibles. Il faut essayer de garder de garder les pieds sur terre, sinon c'est perdu d'avance.
Quand le "politique" veux commence a parler de "technique", (la maison blanche dans ce cas ci) elle n'est pas dans son rôle. Elle peut dire qu'il faut faire plus de code safe, mais pas dire comment. C'est aussi un des problèmes qu'ont les développeurs, voyant passé des "spécifications" où on ne décrit pas clairement ce qu'on lui demande, ou qu'on lui demande l'impossible, mais où on lui dit COMMENT faire. Il faut savoir dire NON, ce qui n'est pas toujours facile. Celui qui dit à ses supérieures qu'il a le feu qui couve là dans un coin, est bien souvent finalement pointé du doigt, car avant qu'il ne dise qu'il y a un feu qui couve, y'avait pas de soucis pour eux, mais une fois la vérité crue découverte, le soucis est là, et il faut trouver un responsable. Et ce responsable, c'est pas toujours le développeur.
Essayons d'avancer dans le bon sens, avec les forces et faiblesses de chacun, en travaillant en équipe. C'est un peu utopique, mais on y parviendra peut-être un jour. Les politiques sont les spécialistes du "il faut que...", mais souvent ils n'ont pas la moindre idée de comment faire se réaliser les choses.
Ceci n'est que l'opinion d'un "vieux briscard", peut-être trop nostalgique d'un temps révolu, mais les plus jeunes, une fois eux aussi devenus moins jeunes, auront aussi ce genre de sentiment. On a tous entendu dans notre enfance "tu comprendras quand tu seras grand". ça nous mettaient en rogne, mais avec le temps, force est de constater que c'est bien souvent le cas.
Bonne journée à tous :-)
Le C++ n'a jamais été un langage sécurisé et il ne le sera jamais. Il n'a pas été conçu pour. Son concepteur l'a justement conçu pour que le développeur soit "libre". Son amour du "bas niveau", la plupart du temps inutile, l'en empêche. Son compilateur laisse tout passer, presque. Il y a toujours eu des alternatives comme Ada, suffisamment orienté-objet pour réaliser tous les systèmes jusqu'aux plus grands. Et pour qui le compilateur est une aide précieuse, sauf si on le débranche explicitement à ses risques et périls (Ariane 5).
Quand à la lisibilité, la plupart du temps, je n'ai pas vu du code C++ écrit pour être lisible par des développeurs et aucun code programmé avec un langage à la syntaxe du C/C++ n'est lisible par l'équipe client non-développeur.
Essayez toujours d'imposer une règle comme "Si le client en revue de code ne l'accepte pas, réécrivez"... En Ada, ou en d'autres langages qui sont de l'Anglais standardisé, il est possible, et c'est de bonne pratique, que de d'écrire des sources qui sont du pseudo-code, c'est-à-dire du niveau de la conception. On gagne sur les deux tableaux: moins de défauts et moins de travail, donc plus de productivité.
Également, je n'ai jamais vu un seul projet C++ donner une garantie d'achèvement après travaux de trois ans de correction gratuite de défauts. Après trois ans en production, je n'ai jamais vu un projet C++ avoir la productivité finale d'un projet Ada. En effet, si on ne mesure que l'écriture du code, il se peut qu'un développeur C++ aille plus vite. Mais dès lors qu'il faut obtenir de la fiabilité, ce qui exactement l'objet de la publication mentionnée, la productivité s'effondre en corrigeant défaut après défaut, sans jamais obtenir le niveau de fiabilité nécessaire...
C'est le malheur de notre industrie que de préférer le "vite fait mal fait" au "ce qui se conçoit bien s'énonce aisément...", c'est à dire que moins on a de temps, et plus il faut réfléchir et concevoir avant d'y aller. Une seule fois.
Jamais entendu parler ! Je dois être trop vieux. Parlez moi en assembleur, en COBOL, en FORTRAN, en C, en C++, en LISP, en Python, en JAVA,... mais Rust? Connais pas...
Rust a des fondations plus solides que C++, mais ne confondons pas les problèmes intrinsèques au langage et les problèmes culturels qui l'entourent.
À propos de problèmes culturels, dans un sondage de Jetbrains de 2021, parmi les développeurs qui n'écrivaient aucun test automatisé, il y avait :
- 46 % des développeurs C et
- 30 % des développeurs C++ alors qu'il n'y avait que
- 3 % des développeurs Scala.
Là, il s'agit beaucoup plus d'un problème de niveau des développeurs que du langage.
À part ça, hier, j'ai lu un témoignage de Philippe Gaultier sur des projets C++ sur lesquels il a travaillé et il y a plusieurs passages qui m'ont fait rire.
Concernant les fuites de mémoire, c'est à la fois un problème culturel et un problème du langage C++. Beaucoup de développeurs ont appris new et delete avant std::make_unique. En langage C, il n'y a pas de destructeur appelé automatiquement, donc c'est un problème du langage.
Concernant les use after free, c'est un problème des langages C et C++, car ils n'ont pas le borrow checker de Rust.
Mais, en entreprise, si tu dis que la plupart du code C++ que tu as lu n'était même pas lisible par des développeurs C++, ce n'est pas la faute du C++, en tout cas pas si on le compare aux autres langages mainstreams. Par exemple, si le problème n'est pas bien décomposé en sous-problèmes ou si les fonctions et les variables sont mal nommées, ce n'est pas en passant à un autre langage de programmation que cela corrigera le problème.
Du pseudo-code relu par des gens qui ne sont pas développeurs ?! Cela m'étonne, à moins qu'il s'agisse de personnes qui ont un peu appris la programmation pendant leurs études post-bac puis qui se sont orientées vers autre chose. Quel est le profil des relecteurs que tu évoques ?
Surtout que ce n'est rapide qu'au tout début. Après accumulation de la dette technique, on bascule dans la phase "lentement fait mal fait" avec plein d'incidents en prod.
Il me semble que l'on peut distinguer dans les fuites mémoire et autres celles qui sont liées directement à la
programmation d'un système d'exploitation de celles qui résultent du développement d'applications sur ce système.
Dans ce dernier cas il n'y a pas de fatalité aux fuites mémoire, c'est une question d'écriture du code. Ces cas mis en
avant de vulnérabilités ou de comportements instables restent marginaux .
Le développement d'une application peut être le résultat d'une succession de développeurs dont les pratiques coïncident mal.
Et qui induisent des bogues.
Aucun intérêt à répéter sans cesse fuite mémoire pour mettre en avant Rust.
Maintenant si le niveau d'acuité des développeurs baisse alors oui mettre un garde fou comme Rust.
Mais à priori il n'y a aucune raison pour que ceux-ci écrivent des aberrations.
Peut-être que la Maison Blanche ait peur que les Russes ou les Chinois corrompent les logiciels de la défense ou autres secteurs stratégiques .
Il ne vous a pas échappé qu'une majorité d'applications en C++ et C tournent sans problème majeur même si le cycle des mises à jour
produit du code nouveau.
Peut être que la Maison Blanche ait peur que les Russes ou les Chinois corrompent les logiciels des secteurs sensibles aux Etats-Unis ?
Attention de ne pas confondre les fuites mémoire et les erreurs de sureté mémoire.
Les fuites mémoires sont gênantes car elles entrainent une surutilisation des ressources, mais elles ne sont pas un risque de sécurité important car leur comportement reste parfaitement défini. Au pire elles peuvent servir à provoquer un déni de service (ralentissement, crash), mais ça ne permet pas de détourner le fonctionnement de l'application pour en prendre le contrôle ou en extraire des donnée sensibles.
Les problèmes de sureté mémoire découlent d'une utilisation invalide de la mémoire (dépassement de buffer, accès mémoire non allouée, accès à des données non initialisées, ...) qui provoque un comportement indéfini. Ce comportement indéfini pouvant être exploité pour détourner l'application de son fonctionnement normal.
Si l’exigence de sécurisation de vos logiciels n'est pas particulièrement élevée, peut-être, mais sinon les erreurs mémoire ne sont absolument pas à négliger.
La grande majorité des failles de sécurité que l'on trouve dans les logiciels en C et C++ sont la conséquence d'erreurs mémoire.
Pour le coup, tout le monde est d'accord pour dire que le problème se produit suite à une erreur de programmation, donc c'est un facteur humain. Maintenant, la question est "qu'est ce qu'on fait pour éviter ça", parce qu'avoir un coupable ne résout pas le problème.
On pourrait dire qu'il suffit d'avoir des gens compétents et bien formé, mais on sait bien que dans la pratique les équipes seront toujours imparfaites, les développeurs parfaitement adaptés ne poussent pas dans les arbres, et même les meilleurs font parfois des erreurs. On trouve des problèmes de sécurité mémoire même dans des grosses équipes d'experts.
L'avantage de Rust est de garantir que les différents développeurs appliqueront sans erreur toutes des bonnes pratiques qui garantissent un code sans problème de sécurité mémoire, et ce, même s'ils ne maitrisent pas encore tout le projet ou s'ils ne sont pas bien concentrés parce qu'ils sont dans un mauvais jour.
Ça à d'autant moins d’intérêt que Rust ne garantit absolument pas l'absence de fuites, même si il limite pas mal le risque comparé au C. Rust protège surtout complètement contre les erreurs de sureté mémoire.
Et c'est vrai que Rust a bien d'autres qualités que la sureté mémoire, mais ça n'est pas le sujet de la discussion.
Je n'ai pas l'impression que, à expérience égale, le niveau des développeurs ait baissé ces vingt dernières années. Au niveau de la sécurité, je dirais même qu'ils sont globalement plus au courant des problématiques.
Par contre c'est le niveau de sécurité attendu par les clients qui augmente, ainsi que l'efficacité de pirates. Les Black Hat comme les White Hat sont beaucoup plus nombreux et avec des méthodologies toujours plus au points.
Le "sans problème majeur" est plus que discutable. On a régulièrement des patchs qui sortent en catastrophe pour corriger des vulnérabilités déjà exploitées.
Tout le monde n'a pas les mêmes exigence en sécurité, mais les attentes sont plutôt à la hausse maintenant que l'informatique est de plus en plus partout.
Vous pouvez oublier le "peut-être". On sait déjà que les grandes nations on des programmes d'exploitation de failles de sécurité et il y a mêmes des société privées qui vendent leurs service pour cela.
En effet, les relecteurs font partie de la maîtrise d'ouvrage, ce sont des personnes avec des métiers techniques ou commerciaux ayant une culture scientifique ou littéraire mais pas nécessairement de programmation.
Oui, je confirme, le jalon est dur à passer, et nécessite de très bonnes règles de conception et de programmation, si l'on veut que ce genre de profil accepte même de relire.
Par ailleurs, j'adhère totalement à la nécessité des tests, dans le cadre global du plan de validation du logiciel (et du système).
J'ai eu ce problème en C# en utilisant une librairie commerciale écrite en C++ et qui fuitait méchamment.
Après avoir tout essayé, même la tête en bas en récitant des formules magiques. La RAM baissait inexorablement (vu depuis le gestionnaire de tâches), jusqu'à l'écran bleu. Crash mortel qui obligeait à redémarrer un serveur alors que l'appli tournait en temps réel sur une plateforme logistique surbookée. C'était le chaos.
En désespoir de cause, j'ai écrit un petit exécutable indépendant nommé "défragmenteur" que je lançais depuis l'appli, juste avant de la fermer (l'appli).
Défragmenteur attendait 3 secondes et relançait l'appli. Il ne faisait que ça, attendre puis relancer son appelant avec une ligne de commande qui restaurait les variables principales sauvegardées par l'appli avant de quitter.
Le miracle, c'est que je récupérais toute la mémoire perdue dans les memory leaks. Cette intervention m'a valu des félicitations et un succès commercial pour mon employeur.
En effet, chaque New ou malloc demande de la ram au système qui stocke au passage l'id du process. Quand l'application se ferme, tous les malloc et les New du thread actif sont libérés, y compris dans les dll synchrones (qui tournent dans le même thread).
Donc, pour les cas désespérés, il faut fermer le process qui fuite et le relancer.
Ok, effectivement, une fuite mémoire n'est pas une vulnérabilité. C'est un bug sur lequel on n'a pas toujours le contrôle.
Une vulnérabilité comme celles dont parle la Maison Blanche ou la DGSI en France, c'est un "exploit" de hacker qui lui permet de faire des dégâts dans le système ou dans le réseau privé d'une boite.
A grande échelle, ça peut même mettre un pays en faillite. Ca peut espionner, voler, tuer, stopper des machines de survie dans un hôpital, faire exploser des centrales électriques, faire tomber des avions, détruire des stocks d'uranium, provoquer des incendies, des guerres, la destruction de l'humanité, ....
Donc, les politiques qui demandent que le software soit mieux protégé sont bien dans leur rôle.
Si les développeurs maîtrisent le code écrit normalement pas de problème mémoire ou autres. Mais certaines applications complexes reprisent par plusieurs équipes de développement peuvent exposer des failles mémoire ou de buffer overflow ou autres encore. Mais je pense que c'est pas si répandu comme problème. C'est un peu exagéré de voire des défaillances à chaque occasion. Par curiosité sur les milliers d'applications écrites surtout en C et en C++ dans les bibliothèques de Linux à combien estimer le pourcentage d'applications présentant ce type particulier de bogues sur la mémoire ? 1% 5% 10% 20% 40% ...99% . A ma connaissance ce sont surtout les environnements graphiques qui sont souvent conçus avec un certain mépris pour la libération des parties allouées. Maintenant aussi c'est difficile de considérer en vrac toutes les applications pour affirmer cette fatalité des fuites mémoire. Dans certains cas critiques ce problème peut se poser mais c'est excessif d'en faire une généralisation . Toutes les applications ne sont pas muti-threads avec exploitation de mémoire partagée. Avec Internet l"accès aux ports peut aussi poser problème. Il n'y a pas que cette histoire de mémoire en C qui résume les problèmes de sécurité des logiciels.
Il ne faut surtout pas hésiter a lire une conversation avant quand on souhaite participer. Et lire les annonces qui ont lancé une discussion. Ce que tu pense n'a pas beaucoup d'intérêt, c'est ce qu'on observe et qui est documenté qui compte.
EDIT : cela dit, c'est une bonne illustration de pourquoi les gouvernements sont obligés de légiférer sur les problèmes de sécurité (pas uniquement en informatique), plutôt que laisser chaque personne (qui n'y connait rien, majoritairement, moi y compris pour 99% des problèmes de sécurité) penser et décider que cela ne sert à rien.
En C, quand on appelle une fonction d'entrée dans une fonctionnalité importante, on a souvent besoin de grands volumes de mémoire.
Comme on est en procédural pur et dur, on est tenté de déclarer beaucoup de variables locales pour y ranger des structs, des buffers et des tableaux conséquents.
Le problème est que la pile du C est la même que la pile système. Son pointeur est stocké dans le registre SP (stack pointer)
Or, toutes les variables locales d'une fonction C sont stockées dans la pile.
Dès lors, il n'y a pas 36 solutions. Si c'est trop volumineux pour la pile (je n'entre pas dans le détail de pourquoi la taille de pile C est limitée), il faut faire des malloc(...).
Mais voilà, quand on fait un malloc en C, il faut impérativement libérer la mémoire ensuite - sinon, c'est un memory leak - c'est à dire que de retour dans cette même fonction, un second malloc réservera un autre bloc de RAM, le pointeur qui permettait de libérer le premier bloc sera écrasé, perdu à jamais, et ainsi de suite.
C'est là qu'on entre dans un paradoxe. Car on nous a appris à mettre des return un peu partout dans le code. Oui mais si vous avez réservé de la mémoire en entrant dans une fonction, vous devez absolument la libérer au sortir de cette même fonction.
Donc, pas question de mettre des return au milieu du code. Le seul return doit se trouver à la fin de la fonction, juste après les libérations de mémoire. En cas de nécessité (souvent après avoir rencontré une erreur, paramètres insuffisants etc...) il n'est pas question d'afficher un message à l'écran, puis de quitter la fonction. Il faut impérativement faire un branchement vers le code qui fait les free's correspondant aux malloc's faits précédemment.
Comme il est impossible de présumer la portée d'un break, qui dépend de degré d'imbrication du code qui a généré l'erreur, souvent dans un switch case,
1. soit on entre dans l'aventure des flags d'erreur testé dans toutes les boucles suivantes,
2. soit on fait ce que n'importe quel esprit économe conclut : un magnifique GOTO. Fustigé par toutes les écoles, publications et autres mais quasiment incontournable dans ce cas, à moins d'écrire son propre gestionnaire mémoire interne, il faut remplacer les return dans la fonction par des goto sortie. J'ai écrit un gestionnaire de mémoire "maison" qui est resté une grosse galère, très sensible au bugs irrécupérables (programme gelé). Tout ça pour éviter un GOTO, c'est vraiment ballot.
On peut dire qu'à lui seul, il justifie pleinement les classes objet avec leur destructeur
Ce cas se présente dans toutes les applications C un peu conséquentes et n'a jamais été traité dans des publications à ma connaissance. Comme le dit OuftiBoy, plus haut, C reste le seul langage disponible pour les micro contrôleurs : Atmel, pic et surtout ESP32 aujourd'hui. Ce dernier possède une stack Wifi IP complète et risque donc de devenir un redoutable zombie pour attaquer des serveurs par saturation. ESP32 est devenu incontournable dans ce domaine et je suis étonné qu'on trouve encore des objets connectés utilisant Atmel (Arduino)
Bon, je m'arrête là. Je n'ai jamais publié mon memory manager en C parce que son fonctionnement repose sur des appels, eux mêmes non sécurisés pour raisons de performance. Si je devais en faire une version pro, ce serait un gros travail et il deviendrait très lent.
On peut disserter des siècles sur cette question... Je mets un break
EDIT : Si quelqu'un est en train de s'arracher les cheveux sur ce problème, plutôt que d'écrire une gestion de mémoire complète, je suggère d'encapsuler les fonctions d'allocation mémoire dans une fonction interne qui renseigne un tableau global des buffers alloués. Il faut gérer ce tableau assez finement pour que les buffers non alloués (ou libérés) soient toujours à (void*) NULL. A certains moments du programme, on peut alors libérer tous les pointeurs encore alloués. C'est l'approche la plus fiable que je connaisse mais elle exige un certain doigté...
Si ça t'intéresse, ce sujet a été abordé dans le fil Les différentes façons de gérer les erreurs en C. Concernant la légitimité de goto en langage C, on est d'accord.
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager