Massive and semantic patching with Coccinelle

I’m currently working on suricata and one of the feature I’m working on change the way the main structure Packet is accessed.

One of the consequences is that almost all unit tests need to be rewritten because the use Packet p construction which has to be replace by an dynamically allocated Packet *. Given the number of tests in suricata, this task is very dangerous:

  • It is error prone
  • Too long to be done correctly

I thus decide to give a try to coccinelle which is a "program matching and transformation engine which provides the language SmPL (Semantic Patch Language) for specifying desired matches and transformations in C code". Well, from user point of view it is a mega over-boosted sed for C.

One of the transformation I had to do was to find all memset() done on a Packet structure and replace it by a memset on the correct length followed by the setting of a pointer. In term of code with "..." meaning some code, I had to found all codes like
[C]func(...)
{
Packet p;
...
memset(&p, 0, ...);
}[/C]
and replace it by
[C]func(...)
{
Packet p;
...
memset(&p, 0, SIZE_OF_PACKET);
p->pkt = (uint8_t *)(p + 1);
}[/C]
To do so, I wrote the following semantic patch which defined the objects and the transformation I want to apply:
[diff]@rule0@
identifier p;
identifier func;
typedef uint8_t;
typedef Packet;
@@
func(...) {
<... Packet p; ... - memset(&p, 0, ...); + memset(&p, 0, SIZE_OF_PACKET); + p.pkt = (uint8_t *)(p + 1); ...>
}
[/diff]
If this semantic patch is saved in the file memset.cocci, you just have to run

spatch -sp_file packet.cocci -in_place detect.c

to modify the file.
The result of the command is that detect.c has been modified. Here's an extract of the resulting diff:
[diff]
@@ -9043,6 +9100,7 @@ static int SigTest...m_type() {
Packet p2;
memset(&p2, 0, SIZE_OF_PACKET);
+ p2.pkt = (uint8_t *)(p2 + 1);
DecodeEthernet(&th_v, &dtv, &p2, rawpkt2, sizeof(rawpkt2), NULL);
[/diff]
As you can see, spatch does not care that the variable is name p2. This is a Packet structure which is defined inside a function and which is memset() afterwards. It does the transformation knowing C and thus you need to think C when writing the semantic patch.

Now let's go for some explanations. The semantic patch start with the declaration of the parameters:
[diff]@rule0@ // name of the rule
identifier p; // this will be replace by the name of a variable
identifier func; // func will be the name of something
typedef uint8_t; // this is a C type we will use
typedef Packet; // same remark
@@
[/diff]
The main point is that, as coccinelle is using variable you must give in the information about what is a variable for you (usage of identifier) but you also need to specify what word are specific to the code (usage of typedef in the example).
The rest is straightforward if we omit an astuce I will detail:
[diff]func(...) { // the modification occurs in any function
<... // there is some code (...) who can occur more than once (<) Packet p; // a variable is a Packet, we named it p ... // some code - memset(&p, 0, ...); // a memset is done on p, we remove it (-) + memset(&p, 0, SIZE_OF_PACKET); // and replace it + p.pkt = (uint8_t *)(p + 1); // by this two lines (+) ...> // the part of the code occuring more than once end here
}
[/diff]

My complete semantic patch for the suricata modification is around 55 lines and the resulting patch on suricata has the following git stat:

30 files changed, 3868 insertions(+), 2745 deletions(-)

and a size of 407Ko. This gives an idea of the power of coccinelle.

Here's a light example of what coccinelle is able to do. If you want to read further just go on coccinelle website or read my "Coccinelle for the newbie" page.

I like to thanks Holger Eitzenberger for talking me about the existence of Coccinelle and I give out a great thanks at Julia Lawall for her expertise and her patience. She helps me a lot during my discovery of Coccinelle.

Using Suricata with CUDA

Suricata is a next generation IDS/IPS engine developed by the Open Information Security Foundation.

This article describes the installation, setup and usage of Suricata with CUDA support on a Ubuntu 10.04 64bit. For 32 bit users, simply remove 64 occurances where you find them.

Preparation

You need to download both Developper driver and Cuda driver from nvidia website. I really mean both because Ubuntu nvidia drivers are not working with CUDA.

I’ve first downloaded and installed CUDA toolkit for Ubuntu 9.04. It was straightforward:

sudo sh cudatoolkit_3.0_linux_64_ubuntu9.04.run

To install the nvidia drivers, you need to disconnect from graphical session and close gdm. Thus I’ve done a CTRL+Alt+F1 and I’ve logged in as normal user. Then I’ve simply run the install script:

sudo stop gdm

sudo sh devdriver_3.0_linux_64_195.36.15.run

sudo modprobe nvidia

sudo start gdm

After a normal graphical login, I was able to start working on suricata build

Suricata building

I describe here compilation of 0.9.0 source. To do so, you can get latest release from OISF download page and extract it to your preferred directory:

wget http://openinfosecfoundation.org/download/suricata-0.9.0.tar.gz

tar xf suricata-0.9.0.tar.gz

cd suricata-0.9.0

Compilation from git should be straight forward (if CUDA support is not broken) by doing:

git clone git://phalanx.openinfosecfoundation.org/oisf.git

cd oisf

./autogen.sh

Configure command has to be passed options to enable CUDA:

./configure –enable-debug –enable-cuda –with-cuda-includes=/usr/local/cuda/include/ –with-cuda-libraries=/usr/local/cuda/lib64/ –enable-nfqueue –prefix=/opt/suricata/ –enable-unittests

After that you can simply use

make

sudo make install

Now you’re ready to run.

Running suricata with CUDA support

Let’s first check, if previous step were correct by running unittests:

sudo /opt/suricata/bin/suricata -uUCuda

It should display a bunch of message and finish with a summary:

==== TEST RESULTS ====
PASSED: 43
FAILED: 0
======================

Now, it is time to configure Suricata. To do so we will first install configuration file in a standard location:

sudo mkdir /opt/suricata/etc

sudo cp suricata.yaml classification.config /opt/suricata/etc/

sudo mkdir /var/log/suricata

Suricata needs some rules. We will use emerging threats one and use configuration method described by Victor Julien in his article.
wget http://www.emergingthreats.net/rules/emerging.rules.tar.gz
cd /opt/suricata/etc/
sudo tar xf /home/eric/src/suricata-0.9.0/emerging.rules.tar.gz
As our install location is not standard, we need to setup location of the rules by modifying suricata.yaml:
default-rule-path: /etc/suricata/rules/
as to become:
default-rule-path: /opt/suricata/etc/rules/
The classification-file variable has to be modified too to become:
classification-file: /opt/suricata/etc/classification.config
To be able to reproduce test,  will use a pcap file obtained via tcpdump. For example my dump was obtained via:
sudo tcpdump -s0 -i br0 -w Desktop/br0.pcap
Now, let’s run suricata to check if it is working correctly:
sudo /opt/suricata/bin/suricata -c /opt/suricata/etc/suricata.yaml -r /home/eric/Desktop/br0.pcap
Once done, we can edit suricata.yaml. We need to replace mpm-algo value:
#mpm-algo: b2g
mpm-algo: b2g_cuda
Now, let’s run suricata with timing enable:
time sudo /opt/suricata/bin/suricata -c /opt/suricata/etc/suricata.yaml -r /home/eric/Desktop/br0.pcap 2>/tmp/out.log
With Suricata 0.9.0, the run time for a 42Mo pcap file is with starting time deduced:
  • 11s without CUDA
  • 19s with CUDA

Conclusion

As said by Victor Julien during an IRC discussion, CUDA current performance is clearly suboptimal for now because packets are sent to the card one at a time. It is thus for the moment really slower than CPU version. He is working currently at an improved version which will fix this issue.
An updated code will be available soon. Stay tuned !

Quand ça fonctionne tout seul

Je venais d’avoir l’idée d’une modification d’ulogd2 pour réaliser la chose pratique d’avoir deux sorties sur la même stack. J’ai donc rajouté pour tester la stack suivante à mon fichier ulogd.conf :

stack=log2:NFLOG,base1:BASE,ifi1:IFINDEX,ip2str1:IP2STR, \\

print1:PRINTPKT,sys1:SYSLOG,mark1:MARK,emu1:LOGEMU

Les tests ont montré que c’était déjà fonctionnel ! D’un coup, la neuvième de Beethoven par Harnoncourt est encore plus grandiose.

Vers une nouvelle agora ?

Récemment, le Nouvel Observateur a réalisé un dossier intitulé “Internet en procès”. Ce dossier a semble-t-il été motivé par l’apparition de plus en plus fréquente d’informations qui font suffisamment de bruit sur Internet pour devoir être reprises par les médias classiques. Le dossier est intéressant mais l’avis des partisans d’un contrôle d’internet me fascine. L’éternel tentation de la censure est toujours bien présente. On peut certes comprendre qu’au vu des affaires récentes (Jean Sarkozy ou Frédéric Mitterand) une envie d’étouffer la contestation naisse dans l’esprit de certaines personnes.

Pour moi, cette envie est d’autant plus forte que la source de l’information n’a pas de visage, ou plutôt qu’elle n’a pas de visage identifiable. Twitter est l’outil par excellence de cette propagation virale et presque anonyme de l’information. Celle-ci se distingue complètement de ce qui se faisait dans les médias standards où tout finit par prendre un visage (le porte parole d’un collectif quel qu’il soit par exemple). Et s’il n’y a pas de visage c’est par un sondage (qui traite de réponses à des questions formulées par le média lui-même) que la voix du peuple s’exprime. Dans cette fabrication de l’information, la communication se fait toujours d’un individu identifié vers le grand nombre. Or, qui dit identification, dit possibilité de contrôle (par contre direct ou par pression par exemple) et c’est pour cela en bonne partie que les médias traditionnels n’effraient aucun homme politique.

Internet fait d’autant plus peur que 2009 a été l’année de l’émergence de Internet comme lieu politique. De nombreux événements ont été architecturés ou conditionnés par Internet :

  • L’élection de Barack Obama qui a fait une campagne utilisant intelligemment les moyens offert par Internet
  • La contestation en Iran (Internet intervenant notamment pour la diffusion des images et pour la synchronisation des manifestants)
  • La manifestation anti-berlusconi du 5 décembre à Rome organisée par des blogueurs

Ces trois événements relèvent du champ de la politique mais Internet est aussi l’endroit de toutes les contestations. J’en tiens pour preuve que Rage Against The Machine a été le numéro 1 de Noël des charts anglais avec “Killing in the Name of” une chanson de 18 ans d’age. L’origine de ce fait inédit est une volonté d’échapper à la “dictature de X-factor” qui s’est matérialisé par un groupe Facebook dont la popularité a explosé en quelques jours. Là aussi, pas de leader charismatique de la contestation mais un intérêt commun qui se nourrit des contributions de chacun et renverse une institution (ici la programmation médiatique de la prise de la tête des charts par le vainqueur de X-factor). Cette histoire est certes anecdotique mais elle montre que l’influence des médias classiques (ici comme prescripteur) peut-être contrée par un mouvement né spontanément sur Internet.

L’équilibre des forces semble être sur le point de basculer. Internet a maintenant la potentialité de devenir une nouvelle agora globalisée, unique et multiple à la fois. Un lieu où une information plus fluide rend possible un échange des idées et un refus de l’arbitraire. Un lieu où des volontés particulières se concertent, se concentrent et font entendre leur voix. Un lieu où des “gus dans un garage” peuvent changer des lois.

GUG !

Mon bureau en mode noyau

Non, non, vous ne verrez pas dans cet article de screenshots du noyau ! J’ai juste envie de poster ici une capture d’écrans que j’ai réalisée et commentée il y a quelque temps. J’étais à ce moment-là en train de réaliser un des mes développements noyau les plus conséquents et cela m’avait conduit à industrialiser mon environnement de travail pour effectuer développements et tests de la manière la plus efficace possible.

Voici donc la capture :

Espace de travail

La résolution est assez élévée puisque mon bureau est constitué d’un écran 19” et d’un 22” placés côte à côte en mode twinview.

Le 22 pouces me permet d’utiliser confortablement un gvim ouvert sur 2 colonnes. Je peux ainsi éditer un fichier en lisant la documentation, ou bien comparer deux fichiers facilement. Sur le 19 pouces de gauche, j’ai fait tourner :

  • le shell pour la compilation du noyau
  • virtualbox pour les tests de modification noyau sans les reboot de machine physique
  • giggle pour l’analyse du patchset en cours de préparation

Je pouvais ainsi étudier les crashs ou les problèmes noyaux tout en lisant le code pour trouver mes erreurs.

Contribution au libre, 2009 commence fort.

Du côté de mes contributions au logiciel libre, l’année 2009 commence assez fort. Il semble que j’ai réussi à déclencher une petite révolution.

Le système de test de NuFW avait mis en évidence un crash rare, non reproductible facilement dans nuauth, le serveur d’authentification de NuFW. Les sorties de gdb ou valgrind révélaient un problème absurde dans la bibliothèque cyrus-sasl. NuFW l’utilise pour réaliser la phase d’authentification des utilisateurs. Le crash apparaissait lors d’un appel à sasl_dispose() qui est la fonction à appeler lorsque l’on a terminé la phase d’authentification. Après maintes vérifications et plusieurs dizaines d’heures de debug, j’étais convaincu que nuauth, le serveur d’authentification de NuFW, utilisait la bibliothèque de manière correcte et que le code environnant était correct.

Lorsque l’utilisation d’une bibliothèque est légitime et que l’on obtient un plantage, c’est que l’on a trouvé un bug. J’ai donc alors commencé à enquêter sur Cyrus-sasl. Cette bibliothèque est développée dans le cadre du projet cyrus (serveur de mail imap) par la Carnegie Mellon University. Elle est utilisée par un nombre conséquent de logiciels libres fameux (dont openldap, sendmail). Même si sendmail a une réputation sulfureuse de sécurité, il est connu pour sa stabilité. Et donc, en me lançant dans le debug de ce problème début septembre 2008, je savais que je m’attaquais à quelque chose de robuste car très utilisé. Le bug allait donc être complexe à trouver.

J’enchainais alors des séances de deboguage plus ou moins longues passant à certain moment plusieurs longues journées de travail (lire 14 ou 15 heures) sur ce problème. Je sortais tout de même victorieux de la confrontation et le 20 septembre 2008, j’envoyais un message à la liste de diffusion cyrus-sasl : [PATCH] Fix problem with sasl_set_mutex

NuFW utilise les bibliothèques cyrus-sasl et libldap_r et libldap_r utilise lui aussi cyrus-sasl. Elle s’en sert lors de la phase d’authentification sur la base LDAP. Comme, et libldap_r et NuFW sont multithreadés ou multithreadable, ils initient tous les deux la bibliothèque cyrus-sasl pour le support des threads. Il y a notamment un appel à sasl_set_mutex() qui définit l’implémentation de mutex à utiliser. NuFW appelle cette fonction avec ses propres paramètres et libldap_r fait de même (même lorsque l’on fait un bind simple, les connaisseurs apprécieront). Or sasl_set_mutex() ne détectait pas qu’une initilisation avait déjà été faite. On avait donc un conflit possible. Les fonctions de mutex sasl prennent des paramètres void* en entrée et travaille sur ces pointeurs. Il y donc potentiellement des casts dangereux.

Dans le cas de NuFW, le problème était beaucoup plus radical. L’initialisation de libldap_r se fait lors du chargement du module ldap de nuauth. Par conséquent, c’est la fonction ldap qui est utilisée après chargement du module. Or, nuauth peut changer de configuration et donc de modules à chaud. Il réalise notamment un déchargement des modules. Or, cela ne met pas à jour la fonction mutex de sasl qui appelle donc une fonction déchargée. Ceci conduit immanquablement au crash. Cette fonctionnalité de modification de configuration à chaud est massivement utilisé dans le système de tests de NuFW et c’est donc pour cette raison que le crash ne se produisait qu’à cet endroit.

J’aurais du déboguer plus rapidement ce problème. La piste que j’aurais du voir plus tôt était l’utilisation de fonctions stockées à des emplacements mémoires non valides. Cette information était donnée par gdb et j’aurais du lui faire d’avantage confiance.

Ma remontée de bug et mon patch ont rapidement été pris au sérieux et un patch implémentant mon idée a été commité dans les sources : Fixed sasl_set_mutex() to disallow changing mutex management functions once sasl_server_init/sasl_client_init is called

J’étais content de voir ce correctif appliqué, mais vu la criticité pour NuFW, j’aurais été satisfait de voir arriver une nouvelle version de cyrus-sasl fixant ce bug. Le problème étant déclenché par une utilisation précise de la bibliothèque, je n’étais pas en droit de remonter mon exigence. De plus, la dernière version de cyrus-sasl date du 19 mai 2006 et je me doutais donc que je n’allais pas être entendu.

Début janvier, un mail envoyé sur la liste a pointé le fait que le bug était reproductible en utilisant le stockage des mots de passe sasl dans ldap : En utilisant lui aussi la bibliothèque libldap_r cyrus-sasl se mordait la queue. Le bug était donc aussi interne à cyrus-sasl. Fort de cette conclusion, j’envoyais une réponse au message signalant le problème :

This made the bug self contained and not dependant of other applications. Given the fact that the effect of this bug is a crash of the calling program, it could be interesting to release a new version of the sasl library. (my 0.02$)

J’avais ainsi osé demandé une nouvelle version sur un logiciel où je n’avais pas écrit une ligne de code. À ma surprise, cela s’est conclu par ce message :  Next release of CMU SASL – call for favorite bugfixes où un membre de l’équipe de développement annonce l’arrivée probable, aux alentours du 15 février, d’une nouvelle version de la bibliothèque et demande quels sont les corrections de bugs que les utilisateurs voudraient voir figurer dans cette version.

Je commence donc l’année 2009, en réussissant à déclencher la sortie d’une nouvelle version d’une bibliothèque qui n’avait pas eu de nouvelles versions depuis près de trois ans !

Je conclus ce poste en plagiant pollux et en revoyant mes objectifs de contributions à la hausse pour l’an prochain :

En 2010, je déclenche une sortie de Debian.

Chrome de Google, attention à vos droits !

Chrome, je pense que presque tout le monde le sait, est le nouveau navigateur développé par google. Il est rapide, sécurisé, simple d’utilisation et surtout pratique pour Google !

Si l’on prend la peinde de lire la licence de Chrome (qu’il est nécessaire d’accepter pour utiliser le logiciel) on découvre des choses hallucinantes :

Vous conservez les droits d’auteur et tous les autres droits en votre possession vis-à-vis du Contenu que vous fournissez, publiez ou affichez sur les Services ou par le biais de ces derniers. En fournissant, publiant ou affichant le contenu, vous accordez à Google une licence permanente, irrévocable, mondiale, gratuite et non exclusive permettant de reproduire, adapter, modifier, traduire, publier, présenter en public et distribuer tout Contenu que vous avez fourni, publié ou affiché sur les Services ou par le biais de ces derniers.

Comment dire simplement, vous donnez un droit d’usage illimité à Google sur l’ensemble des documents et textes passant par le navigateur. Imaginons par exemple que JK Rowling envoie la suite cachée de Harry Potter par webmail à son éditeur en utilisant Chrome. Elle accorde donc gratuitement à google le droit de traduction, publication de l’ouvrage. Pratique !

Mais rassurons-nous en lisant la fin de cette article 11.1 :

Cette licence a pour seul but de permettre à Google d’afficher, de distribuer et de promouvoir les Services et peut être révoquée pour certains Services, selon les dispositions des Conditions supplémentaires applicables à ces Services.

Je suis tout rassuré d’un coup.

GPL contre Skype : 2-0

D’un point de vue juridique, j’aurais du plutôt titrer Welte vs. Skype Technologies SA. En effet, Harald Welte, ex leader du projet Netfilter et fondateur de GPL violations vient de gagner en appel contre Skype Technologies SA.

Harald Welte, dans le cadre de GPL violations, avait commencé à lutter contre Skype Technologies SA en février 2007 pour que la société cesse de violer la GPL en commercialisant des téléphones Wifi sous Linux sans respecter les exigences de la licence.

Faute de réponse de Skype Technologies SA à ses demandes, il avait porté plainte et l’affaire avait été jugée en Juin 2007. Le tribunal avait statué en faveur de GPL violations et Skype Technologies SA avait ensuite fait appel du jugement (GPL 1 – Skype 0).

L’affaire a donc été portée devant le “Oberlandesgericht Muenchen”, plus haute juriduction dans la région de Munich. L’intention de Skype Technologies SA était de nier la validité de la licence GPL mais les juges ne l’entendaient pas de cette manière et Skype Technologies SA a donc retiré son appel après un entretien préliminaire le 08 mai 2008 (GPL 2 – Skype 0).

Spam et astuce d’affichage

J’ai reçu ce spam qui semblait à première vue avoir complètement passé indemne mes logiciels anti-spams. Le sujet notamment n’était pas taggué *SPAM*. Enfin, je ne voyais pas qu’il était taggué :

Received: by d10.nt.com (Postfix, from userid 0)
id D73C21E4490; Thu, 24 Apr 2008 23:03:13 +0200 (CEST)
To: XXXXXXXX@XXX.fr
Subject: Invitation XXXXXXXX 2008
Date: Thu, 24 Apr 2008 23:03:13 +0200
From: SPAMMER <noreply@mailing.spam.com>
Message-ID: <67190e93d75ec77aea41896d6c6d6f89@localhost.localdomain>
X-Priority: 3
X-Mailer: EmailingSoft Powered [version 1.73]
MIME-Version: 1.0
Content-Type: text/html; charset=”iso-8859-1″
Content-Transfer-Encoding: quoted-printable
X-Spam-Score: 7.7 (+++++++)
Subject: *SPAM* Invitation XXXXXXXXX 2008

En mettant le sujet en double, le spammer a réussi à profiter d’une différence de traitement entre le logiciel anti spam et le lecteur de mail. Encore une dépense d’énergie et d’intelligence bien utile…

Led Zeppelin, Mothership

Cela fait plus de 15 ans que j’écoute Led Zeppelin. J’ai donc bien entendu tous les albums en CDs, sans parler des DVDs, cassette vidéo. Vous l’aurez compris, je suis un fan.

C’est donc avec plaisir, que j’ai vu sortir pour Noel une compilation double CD, Mothership, regroupant les meilleurs chansons du groupe. Avec plaisir, car je me suis dit que cela allait permettre le passage de témoin aux jeunes générations. Aayant déjà tous les CDs, je ne pensais vraiment pas en avoir besoin. Le terme “Remasterisé” affiché sur la pochette m’a ensuite fait réfléchir et je me suis dirigé vers un vendeur (de la FNAC) pour savoir si on était dans le registre du flan marketing ou si ce CD avait vraiment été retravaillé par rapport aux CD des albums qui datent de plus de 10 ans. Le vendeur, fan de Led Zep, m’ a confirmé qu’un véritable travail avait été effectué sur les chansons de ce CD. Je l’ai donc acheté et je suis rentré chez moi rapidement pour une séance d’écoute.

Je dispose d’une chaine hifi conséquente : Ampli+CD Cambridge Audio Azur 540, enceintes Elipson Prestige 3. Ce matériel fait des merveilles sur beaucoup de disques mais il est assez exigeant et des enregistrements médiocres le restent vraiment. J’avais été déçu de l’écoute des albums qui offrait un bon son mais sans le petit supplément d’âme ressenti sur d’autres CD. J’attendais donc beaucoup de ce nouveau CD.

Dès les premières notes de la compilation, j’ai compris que le travail effectué lors de la remasterisation était une réussite. Jamais jusque là, je n’avais entendu Led Zeppelin comme cela. Un son spatialisé, souple. L’impression d’avoir Robert Plant en face, la batterie de Bonham qui envahit la pièce sans que l’on ait la sensation d’avoir la tête sous les baguettes, et la guitare de Jimmy Page limpide.

Je suis loin d’être un audiophile averti et c’est encore moins le cas de ma compagne. Subjugué, je lui ai fait écouter le début de Dyer Maker sur l’album et sur la compilation. La réaction a été rapide :

Ça n’a rien à voir

Voilà donc une compilation contenant des titres remasterisés de manière grandiose. C’est beau la technique quand ça fait du bien 🙂