Réutilisabilité du code vs. banalité accidentelle | par Hugo Nguyen
L’un des bugs les plus méchants et critiques pour le consensus (CVE-2018-17144) a été récemment découvert dans le logiciel Bitcoin Core, qui avait auparavant une histoire presque impeccable. Jimmy Chanson a écrit une excellente analyse de ce bug.
Le bref résumé du bug est qu’il existe 4 cas dans lesquels le logiciel Bitcoin Core doit vérifier les doubles dépenses. Les 4 cas partageaient initialement le même flux d’exécution de code. Après quelques itérations subtiles du code sur plusieurs années, l’un des 4 cas (« simple-tx-double-spend-in-a-block ») a été ignoré, ce qui permettrait à un mineur de potentiellement tromper certains nœuds pour qu’ils acceptent un bloc. cela gonfle l’offre de Bitcoin.
La nature de ce bug me rappelle le conflit constant entre :
(a) le besoin de réutilisabilité et d’optimisation du code
(b) le danger de tomber amoureux de ce que j’appelle banalité accidentelle : des choses qui se ressemblent non pas par conception, mais par accident
Les banalités accidentelles créent un terrain fertile pour la refactorisation des cauchemars et des bugs potentiels comme CVE-2018-17144.
Un peu de contexte, si vous n’êtes pas familier avec le génie logiciel :
Dans le domaine des logiciels, il existe une vision grandiose selon laquelle les composants logiciels sont parfaitement modulaires, à l’instar de leurs homologues d’ingénierie physique. Il y a une bonne raison pour laquelle vous n’avez pas besoin de transporter un autre type de chargeur ou de câble USB partout où vous allez.
Il y a donc toujours eu une forte pression en faveur de la réutilisabilité du code. L’écriture de code redondant est souvent mal vue. Pourquoi faire le même travail deux fois quand on peut le faire une fois ?
Il existe également une longue histoire de réinvention de la roue dans le domaine des logiciels, ce qui donne à la réutilisabilité du code une priorité encore plus élevée sur la liste des priorités. La réutilisabilité du code est souvent considérée comme l’une des « meilleures pratiques » de l’industrie. Un aspirant développeur de logiciels junior pourrait être enclin à penser qu’il n’y a aucun inconvénient à la réutilisabilité du code.
Mais il existe un danger caché – et je ne crois pas que ce genre de choses soit jamais enseigné correctement dans les écoles – de réutilisabilité extrême du code.
La réutilisabilité extrême du code signifie la fusion de deux morceaux de code d’apparence similaire en un seul, quels que soient leurs cas d’utilisation et leur intention initiale.
Ce qui finit souvent avec un code qui a un caractère commun accidentel.
Il n’est peut-être pas évident de comprendre pourquoi la banalité accidentelle est mauvaise, mais il suffit de maintenir un projet logiciel suffisamment important pendant une longue période pour comprendre pourquoi.
C’est mauvais parce que les exigences du produit changent et que le logiciel est un produit en constante évolution, jamais vraiment fini.
Ce problème de cible en mouvement constant est quelque chose de tout à fait unique au logiciel. Si vous êtes ingénieur en structure, vous n’êtes pas censé transformer une maison en un immeuble de 20 étages ou une voiture en soucoupe volante. Pourtant, dans les logiciels, nous faisons constamment cela.
Lorsque les exigences du produit et les cas d’utilisation changent, les hypothèses sous-jacentes pour lesquelles le logiciel a été initialement écrit peuvent ne plus être applicables.
Ainsi, ce fier morceau de code commun que vous avez refactorisé (mais que vous avez maintenant complètement oublié) ne fonctionne plus comme vous le pensiez.
J’ai perdu le compte du nombre de projets de refactoring douloureux ou de bugs désagréables que j’ai vus et qui sont le résultat direct d’une optimisation prématurée ou d’une banalité accidentelle – au point où j’évite maintenant des choses comme l’héritage comme la peste.
Les choses qui ont des points communs accidentels révéleront rapidement leurs différences lorsqu’elles évolueront au-delà de leur état initial. Toute rigidité dans le code commun serait alors un énorme fléau dont il faudrait se débarrasser.
Plus il y a de couches de points communs accidentels dans le code, plus il s’agit d’un champ de mines à parcourir. CVE-2018-17144 en est un parfait exemple.
Share this content:




Laisser un commentaire