IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

Les Agences des Five Eyes insistent pour que les organisations abandonnent C++ pour le langage Rust
Qui « offre de meilleures garanties de sécurisation des plages mémoire des logiciels »

Le , par Patrick Ruiz

14PARTAGES

14  0 
»

Faut-il arrêter d’initier de nouveaux projets en C++ et passer à Rust ? La question divise dans la communauté des développeurs dont certains recommandent le langage Rust plutôt que le C ou le C++. Les raisons : la parité du Rust en termes de vitesse d’exécution en comparaison avec le C ; la sécurisation et la fiabilité du Rust en comparaison avec C ou C++. La comparaison entre Rust et C++ vient de prendre un coup de neuf avec une sortie des agences de l’alliance Five Eyes. Elles insistent pour que les organisations abandonnent C++ pour le langage Rust, ce, après que la prise de position du créateur du langage C++ selon laquelle : « la sécurisation des logiciels par le Rust n’est pas supérieure à celle offerte par le C++. »

Les comparatifs des langages Rust et C++ ont un dénominateur commun : la mise en avant de la supériorité de Rust à C++ en matière de sécurisation de la mémoire.

La publication des Five Eyes ne s’en écarte pas : « Les langages de programmation tels que C et C++ sont des exemples de langages de programmation qui peuvent conduire à un code non sûr pour la mémoire et qui sont encore parmi les langages les plus utilisés aujourd'hui. Pour tenter d'atténuer les dangers du code à mémoire non sécurisée obtenu en C et C++, de nombreux fabricants de logiciels investissent dans des programmes de formation à l'intention de leurs développeurs.

Nombre de ces programmes de formation comprennent des tactiques conçues pour réduire la prévalence des vulnérabilités de sécurité de la mémoire produites par ces langages. En outre, il existe de nombreux programmes de formation organisés par des associations commerciales et industrielles. En outre, diverses organisations et universités proposent des formations et un certificat professionnel pour démontrer la connaissance des pratiques de codage sécurisé en C et en C++.

Bien que la formation puisse réduire le nombre de vulnérabilités qu'un codeur peut introduire, étant donné l'omniprésence des défauts de sécurité de la mémoire, il est presque inévitable que des vulnérabilités de sécurité de la mémoire se produisent encore. Même les développeurs les plus expérimentés introduisent des bogues desquels peuvent résulter des vulnérabilités importantes. La formation doit servir de transition pendant qu'une organisation met en œuvre des contrôles techniques plus robustes, tels que des langages à sécurité mémoire. »

« Rust garantit la sécurisation de la mémoire et des threads au moment de la compilation en introduisant des règles de propriété. Il va au-delà du RAII, un mécanisme de gestion de la mémoire couramment utilisé en C++. Il présente deux avantages. Le premier est évident : une fois que le compilateur Rust a validé notre programme, nous n'aurons pas de défauts de segmentation ou de conditions de concurrence lors de l'exécution, ce qui nécessiterait des dizaines d'heures de débogage, en particulier dans une base de code hautement concurrente et principalement asynchrone. La seconde est plus subtile : le compilateur Rust restreint simplement les types de fautes, ce qui réduit les fragments de code étroitement imbriqués qui peuvent causer un tel comportement bogué. La réplication des bogues est considérablement améliorée avec l'aide de l'exécution déterministe », indique l'éditeur RisingWave à propos de la réécriture de son SGBD Cloud natif depuis zéro en Rust après abandon du projet en C++.

C’est une sortie qui fait suite à celle d’Amazon qui est d’avis que « choisir Rust c’est opter pour une meilleure sécurisation des logiciels qu’avec le C, mais une efficacité énergétique et une performance d’exécution que seul le C offre. » En effet, certains benchmarks suggèrent que les applications Rust sont plus rapides que leurs équivalents en langage C. Et c’est justement pour ces atouts que sont la parité en termes de vitesse d’exécution en comparaison avec le C, mais surtout pour la sécurisation et la fiabilité que Mark Russinovich recommande le Rust plutôt que le C ou le C++.



Néanmoins, Bjarne Stroustrup s’inscrit en faux avec le fait que les comparatifs entre Rust et C++ limitent la notion de sécurisation des logiciels à celle de sécurisation de la mémoire : « Il n'y a pas qu'une seule définition de la notion de "sécurité" et nous pouvons réaliser une variété de types de sécurité par une combinaison de styles de programmation, de bibliothèques de support et grâce à la mise à profit de l'analyse statique. » Bjarne Stroustrup suggère ainsi que ce qu’il est possible d’obtenir du C++ en matière de sécurisation des logiciels dépend entre autres du développeur et notamment de la connaissance des outils que lui offre le langage, de sa maîtrise du compilateur, etc.

Des ingénieurs de Google au fait de ce que le C++ leur offre comme possibilités se sont donc lancés dans la mise sur pied dans ce langage d’un borrow-checker. C’est une fonctionnalité du compilateur Rust qui
garantit la sécurisation de la mémoire grâce à une gestion des allocations en mémoire des pointeurs.


L’équipe de Google dont la publication est parue au troisième trimestre de l’année précédente est parvenue à la conclusion que le système de types du C++ ne se prête pas à un tel exercice. Et donc que la sécurisation de la mémoire en C++ est réalisable avec des vérifications lors de l’exécution du programme. En d’autres termes, c’est avec du code C++ lent qu’il est possible d’atteindre un niveau de sécurisation équivalent à celui du Rust.

Code Rust : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include <type_traits>  
#include <utility>  
#include <assert.h>  
#include <stddef.h>  
enum NoRefs {};  
enum HasMutRef {};  
enum HasRefs {};  
template <class T, typename Mode>  
class Own;  
template <class T>  
class MutRef;  
template <class T>  
class Ref;  
template <class T, typename... Args>  
inline Own<T, NoRefs> make(Args... args) {  
  return Own<T, NoRefs>(std::forward<Args>(args)...);  
}  
template <class T>  
inline Own<T, NoRefs> consume(Own<T, HasMutRef> own, MutRef<T> ref) {  
  return Own<T, NoRefs>(std::move(own));  
}  
template <class T>  
inline Own<T, NoRefs> consume(Own<T, HasRefs> own) {  
  return Own<T, NoRefs>(std::move(own));  
}  
template <class T>  
std::pair<Own<T, HasMutRef>, MutRef<T>> mut(Own<T, NoRefs> own) {  
  T* t = own.t_;  
  own.t_ = nullptr;  
  return std::make_pair(Own<T, HasMutRef>(t), MutRef<T>(t));  
}  
template <class T>  
std::pair<Own<T, HasRefs>, MutRef<T>> ref(Own<T, NoRefs> own) {  
  T* t = own.t_;  
  own.t_ = nullptr;  
  return std::make_pair(Own<T, HasRefs>(t), Ref<T>(t));  
}  
// No refs exist.  
template <class T>  
class [[clang::trivial_abi]] Own<T, NoRefs> {  
 public:  
  template <typename... Args>  
  Own(Args... args) : t_(new T(std::forward<Args>(args)...)) {}  
  ~Own() { delete t_; }  
  Own(Own<T, NoRefs>&& other) : t_(other.t_) { other.t_ = nullptr; }  
  T& operator*() const noexcept { return *t_; }  
  T* operator->() const noexcept { return t_; }  
 private:  
  friend Own<T, NoRefs> consume<T>(Own<T, HasMutRef> own, MutRef<T> ref);  
  friend Own<T, NoRefs> consume<T>(Own<T, HasRefs> own);  
  friend std::pair<Own<T, HasMutRef>, MutRef<T>> mut(Own<T, NoRefs> own);  
  friend std::pair<Own<T, HasRefs>, Ref<T>> ref(Own<T, NoRefs> own);  
  Own(Own<T, HasMutRef>&& own) : t_(own.t_) {}  
  Own(Own<T, HasRefs>&& own) : t_(own.t_) {}  
  T* t_;  
};  
// A mut ref exists.  
template <class T>  
class [[clang::trivial_abi]] Own<T, HasMutRef> {  
 public:  
  T& operator*() const noexcept { return *t_; }  
  T* operator->() const noexcept { return t_; }  
 private:  
  friend class Own<T, NoRefs>;  
  Own(T* t) : t_(t) {}  
  ~Own() {}  
  T* t_;  
};  
// Non-mut refs exist.  
template <class T>  
class [[clang::trivial_abi]] Own<T, HasRefs> {  
 public:  
  T& operator*() const noexcept { return *t_; }  
  T* operator->() const noexcept { return t_; }  
  Ref<T> ref() { return Ref<T>(t_, &count_); }  
 private:  
  friend std::pair<Own<T, HasRefs>, Ref<T>> ref(Own<T, NoRefs> own);  
  explicit Own(T* t) : t_(t) {}  
  ~Own() { assert(count_ == 0u); }  
  T* t_;  
  uint32_t count_;  
};  
template <class T>  
class MutRef {  
 public:  
  T& operator*() const noexcept { return *t_; }  
  T* operator->() const noexcept { return t_; }  
  ~MutRef() = default;  
  MutRef(MutRef&& other) : t_(other.t_) {}  
 private:  
  friend std::pair<Own<T, HasMutRef>, MutRef<T>> mut(Own<T, NoRefs> own);  
  MutRef(T* t) : t_(t) {}  
  T* t_;  
};  
template <class T>  
class Ref {  
 public:  
  T& operator*() const noexcept { return *t_; }  
  T* operator->() const noexcept { return t_; }  
  ~Ref() { --(*count_); }  
  Ref(const Ref& other) : t_(other.t_), count_(other.count_) { ++(*count_); }  
  Ref(Ref&& other) : t_(other.t_), count_(other.count_) {}  
 private:  
  friend std::pair<Own<T, HasRefs>, Ref<T>> ref(Own<T, NoRefs> own);  
  Ref(T* t, uint32_t* count) : t_(t), count_(count) { ++(*count); }  
  T* t_;  
  uint32_t* count_;  
};  
MutRef<int> Borrows(MutRef<int> i) {  
  (*i)++;  
  return i;  
}  
TEST(Borrow, HelloWorld) {  
  // Can't do this. The HasMutRefs type is not destructible outside of  
  // consume()in order to have compiler check it is re-owned, but it won't  
  // compile. To pass the HasMutRefs to consume() it has to be destroyed both  
  // inside and outside of consume(). This is true even if trivial_abi is  
  // used and only one destructor would actually run.  
  Own<int, NoRefs> i = make<int>(5);  
  auto& hasmut = mut(std::move(i));  
  MutRef<int> ref = Borrows(std::move(hasmut.second));  
  Own<int, NoRefs> i2 = consume(std::move(hasmut.first), std::move(ref));
}

La sortie des agences Five Eyes intervient dans un contexte où Rust se démarque des autres langages présentés depuis des années comme des alternatives au C et au C++. En effet, le noyau Linux s’ouvre de plus en plus au langage de programmation système de Mozilla.

Après 31 ans, un deuxième langage a fait son entrée pour le développement du noyau Linux : c’est le Rust. La prise en charge de Rust pour le développement du noyau Linux est vue comme une « une étape importante vers la capacité d'écrire les pilotes dans un langage plus sûr. » Rust de Mozilla Research est le type de langage de programmation auquel ceux qui écrivent du code pour des systèmes d’entrée/sortie de base (BIOS), des chargeurs d’amorce, des systèmes d’exploitation, etc. portent un intérêt. D’avis d’observateurs avertis, c’est le futur de la programmation système en lieu et place de langages comme le C ou le C++.

Source : Five Eyes

Et vous ?

Êtes-vous en accord avec les griefs portés à l'endroit de C/C++ en matière de sécurité ? Le problème n'est-il pas plutôt celui de la qualité des développeurs ?
Le C et le C++ ont-ils vraiment besoin de remplaçants surtout en matière de programmation système ?
Votre entreprise a-t-elle adopté le langage Rust ? Si oui, pour quelles raisons ?

Voir aussi :

L'équipe Microsoft Security Response Center recommande l'utilisation de Rust comme approche proactive pour un code plus sécurisé
Quel langage pourrait remplacer C ? Après avoir comparé Go, Rust et D, le choix d'Andrei Alexandrescu se porte sur D
C2Rust : un outil qui permet de faire la traduction et la refactorisation de votre code écrit en langage C vers le langage Rust

Une erreur dans cette actualité ? Signalez-nous-la !

Avatar de Steinvikel
Membre expert https://www.developpez.com
Le 08/12/2023 à 10:47
La comparaison de Rust face à C++ m'a toujours paru assez fallacieuse :
Je la vois toujours évoqué sans tenir compte de l'écosystème du développeur, à croire que ces 2 langages sont comparés nus.

Comparer un langage qui tire parti d'un complément de fonctionnalités par des outils externes, à un autre qui en incorpore certaines en natif, mais le faire sans ces dit outils a-t-il du sens ?

Dans un second temps, Bjarne Stroustrup rappelait à l'occasion de la cppCon 2023 (billet dvp.com du 6 octobre ici) que la question de la sécurité (et la sûreté) n'a pas démarré il y a quelques années, et que les principales règles de codage qui gouverne la sécurité par le code existent depuis au minimum les années 90.
Depuis cette époque la problématique n'a pas changé --> le difficulté n°1 est de trouver une solution pour que la masse des développeurs aient connaissance de ces règles, la difficulté n°2, qu'ils finissent par avoir l'habitude de les appliquer.
La difficulté n°2 vient du fait que l'on code avant tout pour répondre à un besoin pratique, et que parmi tous les aspects à traiter sur les concepts à choisir et leur implémentation, les développeurs finissent par oublier d'appliquer certaines notions de sécurité. En découle des erreurs types, comme :
Les erreurs de logique - où ce qui est écrit s'écarte de la manière dont le codeur le pensait (ex : utiliser '<' là où '>' était pensé)
les fuites de ressources
les erreurs de concurrence
les erreurs de typage
les overflow et les conversions implicites
les erreurs de timing - ex : coder un retour à 1,2 ms à un périphérique qui répond aux évènements externe en 1 ms max
les allocations non prédictibles
les erreurs d'arrêt -

NB : pour les diapos de la conférence : lien_github
NB : pour la conférence :


Il rappel également que bien qu'une alternative soit "memory safety", ce n'est pas suffisant, la sécurité doit être traité globalement, sur tous ses aspects.
Une question revient alors assez souvent : si Rust permet plus facilement de produire du code "memory safety" pour une plus grande part de développeurs, Rust permet-il d'atteindre un plus haut degré final de sécurité ?
Que la réponse soit "oui" ou "non", Rust permet-il à un plus grand nombre de développeurs de produire du code plus sûr ?
A cette dernière question, je pense pouvoir dire "oui", car permet de le faire de manière plus accessible tous niveaux de maîtrise confondu.

Une chose est sûr : l'aspect déterministe du code produit en Rust semble être l'un des atouts majeur en terme de garantie sur la sécurité du code produit et son analyse.
Mais je constate aussi que beaucoup de code produit sont lourd à l'exécution (mémoire, CPU...) parce que le code n'est pas suffisamment verbeux (explicitement écrit).
Un exemple flagrant, lors d'une démonstration par Jason Turner à la cppCon 2016, où après avoir fait un mapping des couleurs, il faisait face à un overhead.
Une simple transformation de " static std::array<Color, 16> colors {{... " en " static const std::array<Color, 16> colors {{... " et ses 354 instructions d'assembleur se transforment tout à coup en 7 instructions.
La conférence cppCon 2016 : lien_youtube
5  0 
Avatar de Pyramidev
Expert éminent https://www.developpez.com
Le 08/12/2023 à 13:40
Citation Envoyé par Regulus136 Voir le message
En fait il faut expérimenter ce langage incroyablement verbeux pour comprendre sa douleur.
Je peux comprendre que Rust soit qualifié de verbeux par rapport à du Python. Mais, qualifier Rust d'"incroyablement verbeux" par rapport à C++, cela m'étonne. Il y a des choses plus concises en C++ et d'autres plus concises en Rust. Aurais-tu un exemple de code "incroyablement verbeux" en Rust sous la main à partager ?
3  1 
Avatar de seedbarrett
Membre éclairé https://www.developpez.com
Le 08/12/2023 à 14:31
Les agences Five Eyes insistent pour que les organisations abandonnent C++ pour le langage Rust
Quand je lis ça, j'ai plutôt envie de rester sur C++
2  0 
Avatar de Uther
Expert éminent sénior https://www.developpez.com
Le 11/12/2023 à 16:38
Citation Envoyé par Steinvikel Voir le message
La comparaison de Rust face à C++ m'a toujours paru assez fallacieuse :
Je la vois toujours évoqué sans tenir compte de l'écosystème du développeur, à croire que ces 2 langages sont comparés nus.
Les deux comparaisons peuvent avoir un sens, il s'agit juste de savoir de quoi on parle.
Bien sur qu'un langage comme Rust n'a pas encore tout l'écosystème de bibliothèques et d'outils qui ont été développé pour C++ pendant plusieurs dizaines d'années, ceci dit c'est un problème qui a déjà bien commencé à se résorber. Si on veut un langage a utiliser immédiatement, c'est bien évidement à prendre en compte au moment du choix.

Ca ne veut pas dire pour autant qu'il n'y a pas d’intérêt à analyser les capacités intrinsèques d'un langage pour savoir ce qu'il permet déjà de faire techniquement, même si les bibliothèques restent a coder, et ce qu'il ne permettra pas de faire, peu importe ce que l'on code.

Citation Envoyé par Steinvikel Voir le message
Comparer un langage qui tire parti d'un complément de fonctionnalités par des outils externes, à un autre qui en incorpore certaines en natif, mais le faire sans ces dit outils a-t-il du sens ?
Il faudrait préciser ce que tu entends par là car Rust comme C++ sont relativement indépendant d'outils externes, pour le fonctionnement de base des langages au moins.

Citation Envoyé par Steinvikel Voir le message
Dans un second temps, Bjarne Stroustrup rappelait à l'occasion de la cppCon 2023 (billet dvp.com du 6 octobre ici) que la question de la sécurité (et la sûreté) n'a pas démarré il y a quelques années, et que les principales règles de codage qui gouverne la sécurité par le code existent depuis au minimum les années 90.
Depuis cette époque la problématique n'a pas changé --> le difficulté n°1 est de trouver une solution pour que la masse des développeurs aient connaissance de ces règles, la difficulté n°2, qu'ils finissent par avoir l'habitude de les appliquer.
La difficulté n°2 vient du fait que l'on code avant tout pour répondre à un besoin pratique, et que parmi tous les aspects à traiter sur les concepts à choisir et leur implémentation, les développeurs finissent par oublier d'appliquer certaines notions de sécurité.
Si c'est vrai que comme le dit Stroustrup dans sa conférence, la sécurité du C++ a évolué tout au long de son histoire, ça a quand même été, pendant très longtemps, une préoccupation secondaire bien derrière la performance et la compatibilité. Il y avait certes de bonnes raisons de faire ce choix, mais, l'état actuel du C++ au niveau de la sécurité en est clairement la conséquence. Bjarne Stroustrup ne se penche sérieusement sur la sécurité du C++ que depuis qu'il y est poussé par l'arrivée des langages de bas niveau alternatifs et par les autorités de sureté.

Là ou il me parait très lucide dans sa conférence, c'est quand il dit clairement : "Being careful does not scale" (Être prudent n'est pas tenable à grande échelle). Ca change des discours qu'on peut entendre encore bien trop souvent sur le C et le C++. Par contre, une bonne partie de son discours ressemble pas mal à du déni des problèmes. En même temps c'est dur de lui reprocher de défendre son bébé. Quand il dit qu'il n'y a pas que la sécurité mémoire à prendre en compte, c'est vrai, mais c'est quand même de l'ordre des 2/3 des vulnérabilités critiques dans la plupart des grosse bases de code C++, y compris celles moderne et surveillées. Et pour les autres type de problème de sécurité qu'il évoque, le C++ est là encore à la traine comparé a ses alternatives modernes.

Citation Envoyé par Steinvikel Voir le message
Mais je constate aussi que beaucoup de code produit sont lourd à l'exécution (mémoire, CPU...) parce que le code n'est pas suffisamment verbeux (explicitement écrit).
Un exemple flagrant, lors d'une démonstration par Jason Turner à la cppCon 2016, où après avoir fait un mapping des couleurs, il faisait face à un overhead.
C'est le coté potentiellement surprenant des optimisations, mais pour le coup ce genre de chose peut tout aussi bien arriver en C++ qu'en Rust
2  0 
Avatar de Uther
Expert éminent sénior https://www.developpez.com
Le 14/12/2023 à 3:29
Citation Envoyé par mintho carmo Voir le message
Je suis d'accord que le comité n'a pas explicitement déprécier beaucoup de syntaxes, pour autant, je suis pas d'accord avec le "pas facilement identifiables". Les problèmes de sécurité du code et les bonnes pratiques sont des choses qui sont largement documenté depuis plus de 20 ans, dans des livres, des blogs, des talks, etc.
Les bonne pratiques ça clairement ces limites. Tu as des gens plus ou moins formés, avec une pratique plus ou moins avancée. Malgré une formation, on peut facilement avoir de mauvaises conceptions. Par exemple, contrairement à ce que tu disais, il ne suffit pas d'utiliser vector ou string : il faut aussi faire attention à comment on les utilise. Je suppose que tu étais bien au courant et que tu as expliqué ça de manière un trop simplifiée, mais c'est typiquement le genre de soucis qui va arriver, que ça soir par mauvaise compréhension du concept ou inattention à l'utilisation.
Les usages à risques sont plus difficile a voir dans la pratique que dans les exemple de cours. Même les experts, à jour, et qui pratiquent en permanence, finissent fatalement par faire des erreurs car les fonctionnalités problématique sont trop facilement accessible par inadvertance.

Le fait que le compilateur te refuses simplement les usages à risque change complètement la donne.

Citation Envoyé par mintho carmo Voir le message

Les raisons que j'ai entendu le plus souvent pour la non utilisation des "bonnes pratiques", c'est pas "je savais pas que ca existait", mais :
- "ca marche bien comme ca, avec mon vieux code" (non, tu teste comme un singe et c'est pour ca que tu vois pas les bugs)
- "je dois maintenir du code legacy" (ca n'empêche pas de faire évoluer le code et c'est aussi ton boulot d'expert d'expliquer aux décideurs le cout de maintenir le code legacy plutôt que le faire évoluer)
- "pas le temps de me former" (et c'est pour ça que tu es obsolète et que ton code est mauvais)
- etc
C'est la dure loi de la réalité et on ne peut pas faire comme si ça n'existait pas.
C'est une bonne partie de la raison pour laquelle le fait que le langage ne tolère pas de cacher facilement la merde sous le tapis est utile.

Citation Envoyé par mintho carmo Voir le message
Mais, dans la même idée, les erreurs évitables par Rust sont qu'une (petite) partie des bugs que l'on retrouve sur les applications. Quand on regarde par exemple la publication des vulnérabilités sur OpenSSL, c'est beaucoup des erreurs de logique, des choses qui ne sont pas détectables par Rust ou des sanitizers. Je pense que c'est dans ce sens que Stroustrup parlait de sécurité globale. Je suis juste pas du tout convaincu, pour le moment, que l'utilisation de Rust aura un impact significatif sur mon travail de tous les jours et la qualité de mes codes.
J'ai regardé vite fait les CVE d'OpenSLL de cette année. C'est environ 40% de toutes les CVE qui sont dues à gestion mémoire, ça monte à 60% si regarde les CVE de sévérité moyenne ou plus. C'est globalement ce qu'on constate sur la plupart des projets C++ conséquents : environ les deux tiers des vulnérabilités importantes sont liées à des problèmes de sécurité mémoire.

Citation Envoyé par mintho carmo Voir le message
Il n'y a justement pas besoin de quoi que ce soit de la part du comité. C'est juste une question de choix de la part des devs de ne plus utiliser certaines syntaxes, certains idioms, suivre certaines pratiques, sans qu'il soit nécessaire de déprécier quoi que ce soit.
Sauf que la pratique a démontré que ça ne marche pas. C'est ce qu'entent Biarne Stroustrup quand il dit "Being careful does not scale". Sur un code suffisamment compliqué il y aura forcément une mauvaises utilisations involontaires si on ne met pas en place des garde-fous.
2  0 
Avatar de fdecode
Membre régulier https://www.developpez.com
Le 08/12/2023 à 16:44
Citation Envoyé par Pyramidev Voir le message
Mais, qualifier Rust d'"incroyablement verbeux" par rapport à C++, cela m'étonne.
Moi aussi, ça m'étonne. En ce qui me concerne, je trouve que ce langage permet de produire du code élégant, et surtout j'aime la manière dont il permet de structurer les librairies dans une perspective de généricité.

Ceci-dit, les contraintes liées aux sémantiques d'emprunt et de durée de vie peuvent parfois demander un certain exercice intellectuel si on veut aboutir à un code léger.

Et si on se laisse aller à utiliser les puissants paradigmes de rust n'importe comment, on peut aussi produire du code un peu lourd (e.g. des codes génériques avec des contraintes sur les variables de type un peu dans tous les sens...).

Il faut aussi programmer avec la philosophie des paradigmes de Rust et adapter ses réflexes en ce sens. A contrario, je me souviens au début m'être exercé à simuler des classes d'objets au sens 'classique' en utilisant les mécanismes de traits, de mod et de généricité (histoire de me prouver que rust avait l'expressivité suffisante pour programmer objet de la manière que je l'avais appris...). J'y suis arrivé, mais c'était très lourd!

La programmation des macros (procédurales ou non) n'est pas particulièrement légère non plus, de mon point de vue.

Mais il ne s'agit pas là de cas d'usage usuels.
1  0 
Avatar de mintho carmo
Membre confirmé https://www.developpez.com
Le 11/12/2023 à 23:53
Citation Envoyé par Uther Voir le message
Si c'est vrai que comme le dit Stroustrup dans sa conférence, la sécurité du C++ a évolué tout au long de son histoire, ça a quand même été, pendant très longtemps, une préoccupation secondaire bien derrière la performance et la compatibilité. Il y avait certes de bonnes raisons de faire ce choix, mais, l'état actuel du C++ au niveau de la sécurité en est clairement la conséquence. Bjarne Stroustrup ne se penche sérieusement sur la sécurité du C++ que depuis qu'il y est poussé par l'arrivée des langages de bas niveau alternatifs et par les autorités de sureté.
Je suis d'accord en partie. Mais il faut quand même préciser que la sécurité a toujours fait partie des préoccupations d'une partie du comité. Le principe même du RAII (cité dans l'article) date du début de la standardisation du C++. Par exemple auto_ptr a l'époque, mais également string, vector, etc.

Mais quand on regarde les CVE/CWE (les vulnérabilités les plus communes), on voit que beaucoup sont liées à des buffer overflow, des memory leaks, etc. Des choses qui sont résolus depuis longtemps en C++ simplement en utilisant des string ou des vector, par exemple. On voit d'ailleurs dans l'article que la confusion C et C++ continue d'être faite.

Et c'est le point où je voulais arriver : à mon sens, c'est pas juste (voire : pas principalement) un problème de langage et de comité, mais d'utilisateurs. On voit encore des débutants qui apprennent le C++ avec du code qui date d'il ya 20 ans. Et des pros faire pareil. Qui refuse d'apprendre les "nouvelles" pratiques (qui datent depuis plus de 20 ans !), les nouveaux designs, les nouveaux outils.

Une grosse partie de l'intérêt de passer à un nouveau langage (Rust ou autre), c'est aussi de faire le tri entre les devs qui acceptent de se former, de réécrire leurs codes en suivant de nouvelles pratiques, en acceptant de supprimer l'ancien code non safe, etc. De plus, ce sont des projets qui se prêtent bien à la sécurisation, avec peu de code "unsafe" en Rust. (J'ai en tête par exemple la réécriture de binutils, qui n'est pas safe, mais utilise des char* partout. L'équivalent en C++ avec string sera safe sans aucun problème). Si un nouveau projet devait démarrer en C++, mais avec des devs qui sont formés, avec un code from scratch et un design orienté vers la sécurité, en mettant en place les outils, etc. est-ce qu'on n'aurait pas une sécurité équivalente à Rust ?

Il faut reconnaître que la comparaison entre Rust et C++ est biaisée du fait que l'on compare souvent des nouveaux projets from scratch + équipe neuve qui veulent de la sécurité, versus du code legacy en C++ avec des équipes hétérogènes en compétences et motivations.

Citation Envoyé par Uther Voir le message
Il faudrait préciser ce que tu entends par là car Rust comme C++ sont relativement indépendant d'outils externes, pour le fonctionnement de base des langages au moins.
Je pense qu'il parle du fait qu'une partie de la sécurité du C++ vient aussi des outils externes d'analyse statiques (clang sanitizer et autres). Si un langage "choisie" de détecter une vulnérabilité via le compilateur/sanitizer ou que cela soit fait via la sémantique du langage, on pourra obtenir le même niveau de sécurité sur cette vulnérabilité... à partir du moment où les devs choisissent d'activer cette détection ET de les corriger.

Un langage qui intègre cette vérification dans sa sémantique sera plus sure, parce qu'elle laisse pas le choix aux devs. Mais au final, c'est pas forcément pertinent de comparer uniquement les langages, et pas les langages dans un écosystème complet. Et on est bien sur un problème de pratiques de devs. (Mais je dis pas non plus que toutes les vulnérabilités fixées par Rust ont un équivalent en C++ via les outils externes).

Citation Envoyé par Uther Voir le message
savoir ce qu'il permettra de faire même si ce n'est pas encore prêt et se qu'il ne permettra jamais de faire.
C'est vrai par rapport a Rust et son manque d'écosystème actuel.

Mais cela est également vrai par rapport au C++ et l'évolution future de ses outils de sécurité.

On voit beaucoup d'évolutions du C++ et des outils qui sont directement inspirées d'autres langages, en particulier de Rust ces derniers temps. Choisir de nos jours de commencer un nouveau projet est aussi un pari sur les évolutions de ces 2 langages et de leurs écosystèmes. Mon pari est que justement, l'évolution future du C++ fera que l'on aura ("a" déjà, selon le type de projet) une sécurité équivalente à Rust.

Dès maintenant, la majorité des bugs sur lesquels je bosse en C++ ne sont pas liés à de la sécurité mémoire. Et la réécriture en Rust (si on imaginait qu'il n'y a aucun coût de formation et de réécriture) des projets sur lesquels je bosse n'aurais pas ou peu d'impact sur la quantité de bugs a corriger ou la facilité d'ajouts de fonctionnalités. (Ou cela nécessiterait de passer par des "unsafe" en Rust)
1  0 
Avatar de Uther
Expert éminent sénior https://www.developpez.com
Le 13/12/2023 à 6:29
Citation Envoyé par mintho carmo Voir le message
Je suis d'accord en partie. Mais il faut quand même préciser que la sécurité a toujours fait partie des préoccupations d'une partie du comité. Le principe même du RAII (cité dans l'article) date du début de la standardisation du C++. Par exemple auto_ptr a l'époque, mais également string, vector, etc.
Je dis bien que la sécurité fait partie des préoccupations, mais c'est loin d'être une priorité et quand il faut trancher entre la sécurité ou les performance et la compatibilité, la sécurité n'est généralement pas gagnante jusqu’à présent. Oui il y a eu des évolutions, mais peu ont été faites avec pour but de garantir la sécurité. Typiquement les vector et string ne sont pas du tout sécurisés contre les dépassement et l'invalidation des références. auto_ptr a plus été pensé pour éviter les fuites (et encore très partiellement) que pour prévenir des usages mémoire invalides.

Citation Envoyé par mintho carmo Voir le message
Mais quand on regarde les CVE/CWE (les vulnérabilités les plus communes), on voit que beaucoup sont liées à des buffer overflow, des memory leaks, etc. Des choses qui sont résolus depuis longtemps en C++ simplement en utilisant des string ou des vector, par exemple. On voit d'ailleurs dans l'article que la confusion C et C++ continue d'être faite.
Les vector et string ne protègent pas des dépassement, du moins pas si on utilise les crochets qui sont pourtant la syntaxe la plus naturelle. De plus ils permettent d'obtenir des références à du contenu en mémoire qui peut devenir invalide.
Les leaks mémoire sont pas des risques de vulnérabilité graves : le plus souvent le programme consomme juste trop de mémoire, au pire ça permet un DOS mais pas une execution de code arbitraire ou du vol de données.

Citation Envoyé par mintho carmo Voir le message
Et c'est le point où je voulais arriver : à mon sens, c'est pas juste (voire : pas principalement) un problème de langage et de comité, mais d'utilisateurs. On voit encore des débutants qui apprennent le C++ avec du code qui date d'il ya 20 ans. Et des pros faire pareil. Qui refuse d'apprendre les "nouvelles" pratiques (qui datent depuis plus de 20 ans !), les nouveaux designs, les nouveaux outils.
Le problème ne vient pas que des utilisateurs. Le langage n'a pas fait grand chose pour pousser les utilisateurs à migrer vers les nouvelles pratiques, pour cela il aurait du déprécier ce qui est problématique. Malheureusement, le gros problème du C++, c'est qu'il est bâti sur un long héritage (qui remonte au C) qui n'a jamais pris en compte la sécurité comme un élément important. Il n'y a pas de sous-ensemble sûr clairement défini, qui ne serait pas incompatible avec 95% de l'existant.
C'est difficile de reprocher aux gens de ne pas utiliser les bons outils quand ils ne sont pas facilement identifiables.

Citation Envoyé par mintho carmo Voir le message
Une grosse partie de l'intérêt de passer à un nouveau langage (Rust ou autre), c'est aussi de faire le tri entre les devs qui acceptent de se former, de réécrire leurs codes en suivant de nouvelles pratiques, en acceptant de supprimer l'ancien code non safe, etc.
Ca va quand même au delà. En Rust, un programmeur qui viendrait du C++ avec de mauvaises pratiques et qui voudrait faire le même type de code n'y arrivera pas sans utiliser un bloc unsafe. Quelque part c'est une formation obligatoire à la sécurisation.
Ca ne veut pas dire qu'il fera un code Rust de qualité, mais au moins on a la garantie qu'il ne fera une bonne partie des erreurs qui pourraient causer une faille de sécurité en C++.

Citation Envoyé par mintho carmo Voir le message
Je pense qu'il parle du fait qu'une partie de la sécurité du C++ vient aussi des outils externes d'analyse statiques (clang sanitizer et autres). Si un langage "choisie" de détecter une vulnérabilité via le compilateur/sanitizer ou que cela soit fait via la sémantique du langage, on pourra obtenir le même niveau de sécurité sur cette vulnérabilité... à partir du moment où les devs choisissent d'activer cette détection ET de les corriger.
Dans le cas des sanitizers en effet ils méritent d'être pris en compte, sachant quand même que ce sont des outils dynamiques, certes très utiles, mais qui ne garantissent pas une couverture exhaustive des cas d'utilisation du code. Je pense que tout projet important se soucie un minimum de la sécurité et les utilise déjà, donc je doute que ça ait une importance énorme sur les chiffres de vulnérabilité des gros projets.

Citation Envoyé par mintho carmo Voir le message
On voit beaucoup d'évolutions du C++ et des outils qui sont directement inspirées d'autres langages, en particulier de Rust ces derniers temps. Choisir de nos jours de commencer un nouveau projet est aussi un pari sur les évolutions de ces 2 langages et de leurs écosystèmes. Mon pari est que justement, l'évolution future du C++ fera que l'on aura ("a" déjà, selon le type de projet) une sécurité équivalente à Rust.
Je pense en effet que ça serait une bonne voie mais je vois mal comment faire un C++ aussi sécurisé que Rust sans déprécier tellement de choses que ça en deviendrait presque un dialecte séparé, et ça poserait énormément de défis avec l'historique de C++. Je ne suis pas certain que ça serait faisable facilement au sein du comité.
Pour le coup les pistes d'évolution du type CppFront, Carbon ou Circle me semblent plus réalistes.

Citation Envoyé par mintho carmo Voir le message
C'est vrai par rapport a Rust et son manque d'écosystème actuel.
Mais cela est également vrai par rapport au C++ et l'évolution future de ses outils de sécurité.
Ce que je voulais dire c'est plutôt qu'il est intéressant d'analyser les capacités intrinsèques d'un langage pour savoir ce qu'il permet déjà de faire techniquement (même si certaines bibliothèques restent à coder), et ce qu'il ne permettra pas de faire à moins d'un évolution technique.

Parier sur les évolutions d'un langage, c'est beaucoup plus spéculatif. C'est sympathique dans un forum de programmeurs, mais j’éviterais vraiment pour toute décision sérieuse.
1  0 
Avatar de fdecode
Membre régulier https://www.developpez.com
Le 13/12/2023 à 9:44
Citation Envoyé par Uther Voir le message
Ca va quand même au delà. En Rust, un programmeur qui viendrait du C++ avec de mauvaises pratiques et qui voudrait faire le même type de code n'y arrivera pas sans utiliser un bloc unsafe. Quelque part c'est une formation obligatoire à la sécurisation.
Ca ne veut pas dire qu'il fera un code Rust de qualité, mais au moins on a la garantie qu'il ne fera une bonne partie des erreurs qui pourraient causer une faille de sécurité en C++.
Je vois néanmoins un problème dans l'utilisation des blocs unsafe pour quelqu'un venant du C/ C++ : il est indispensable de savoir ce qui est undefined behavior et ce qui ne l'est pas. Et cette connaissance demande une certaine maîtrise de Rust et peut-être des bases théoriques et une connaissance de la compilation. Par exemple, le fait que le compilateur puisse faire de l'optimisation de code en utilisant la connaissance sur le type de référence (non mutable `&` ou mutable `& mut`) fait qu'un code unsafe peut avoir un comportement différent en mode Debug ou en mode Release (optimisé) si on a eu la mauvaise idée de transformer une référence non mutable en référence mutable par un bloc unsafe.
1  0 
Avatar de Regulus136
Membre à l'essai https://www.developpez.com
Le 08/12/2023 à 11:48
On aimerait bien que les personnes qui osent sortir un avis aussi tranché aient codé au minimum une application en langage Rust. Parce que si programmer (correctement) en C++ (1X/2X) réclame des compétences sérieuses et un investissement important, alors programmer en Rust est autrement plus délicat. En fait il faut expérimenter ce langage incroyablement verbeux pour comprendre sa douleur.
2  2