Un compilateur totalement sûr les allocations mémoire ?

Le
Stéphane Zuckerman
Bonjour,

En effectuant quelques recherches sur le net, je suis tombé sur cet
article :

« Implementation of the memory-safe full ANSI-C compiler » (PLDI
2009).
(URL : http://www.informatik.uni-trier.de/~ley/db/conf/pldi/pldi2009.html)

Je suis en train de m'atteler à sa lecture, mais je me demandais si
quelqu'un avait eu vent de cette implémentation et si il/elle avait
des commentaires (« marchera jamais en vrai »/« trop cool gigalol
») Si on a la certitude d'avoir une mémoire correctement géré d=
ès
la compilation sans trop de perte de performances, je trouve ça plutôt
intéressant

Stéphane
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
-ed-
Le #19764711
On 15 juil, 18:50, Stéphane Zuckerman wrote:
Bonjour,

En effectuant quelques recherches sur le net, je suis tombé sur cet
article :

« Implementation of the memory-safe full ANSI-C compiler » (PLDI
2009).
(URL :http://www.informatik.uni-trier.de/~ley/db/conf/pldi/pldi2009.html)



Il semble que l'accès au document ne soit pas libre...

De plus, je ne vois pas ce qui empêche en C standard, d'utiliser la
mémoire correctement et sans erreurs...
Richard Delorme
Le #19764941
Le 16/07/2009 02:52, -ed- a écrit :
On 15 juil, 18:50, Stéphane Zuckerman wrote:
Bonjour,

En effectuant quelques recherches sur le net, je suis tombé sur cet
article :

« Implementation of the memory-safe full ANSI-C compiler » (PLDI
2009).
(URL :http://www.informatik.uni-trier.de/~ley/db/conf/pldi/pldi2009.html)



Il semble que l'accès au document ne soit pas libre...




On peut trouver la thèse de l'auteur (traduite en anglais) ici :

http://www.taplas.org/~oiwa/thesis.pdf

J'ai parcouru très vite. Le principe consiste à utiliser un pointeur
"intelligent" qui détecte les principales erreurs (pointeur non
initialisé, accès hors tableau, etc.) pour, en général, terminer le
programme proprement. Ça évite certaines attaques, mais ça ne résoud pas
tous les problèmes.


De plus, je ne vois pas ce qui empêche en C standard, d'utiliser la
mémoire correctement et sans erreurs...



La bêtise humaine, malheureusement très répandu (je suis moi-même
contaminé). A noter que le programme de M. Iowa est un compilateur de C
standard, qui ne change rien au langage.

--
Richard
-ed-
Le #19765161
On 16 juil, 07:37, Richard Delorme
> De plus, je ne vois pas ce qui empêche en C standard, d'utiliser la
> mémoire correctement et sans erreurs...

La bêtise humaine, malheureusement très répandu (je suis moi-même
contaminé). A noter que le programme de M. Iowa est un compilateur de C
standard, qui ne change rien au langage.



Quelques méthodes de travail simpples permettent de vérifier ce qu'on
fait...

J'utilise la vérification de la présence du dernier 0 d'une chaine
pour savoir si il y a eu débordement ou non. (OK, si il y a eu
débordement grave, le comportement étant indéfini, la méthode ne
fonctionne pas toujours).

http://www.bien-programmer.fr/clib.htm
Extrait de sys.h :

/* controles */
#define LIM_STR(s) (s)[sizeof (s) - 1]=0
#define CHK_STR(s) ASSERT((s)[sizeof (s) - 1]==0)

#ifndef NDEBUG
#define LIM_PTR(p,l) (p)[(l) -1]=0
#else
#define LIM_PTR(p,l)
#endif
#define CHK_PTR(p,l) ASSERT((p)[(l) -1]==0)

Sinon, pour les tableau, un assert() bien placé, avec une condition
correctement établie, qui vérifie les index avant usage suffit à
détecter les erreurs.
Richard Delorme
Le #19769361
Le 16/07/2009 08:23, -ed- a écrit :
#ifndef NDEBUG
#define LIM_PTR(p,l) (p)[(l) -1]=0
#else
#define LIM_PTR(p,l)
#endif



A mon avis, c'est ce genre de code qui est particulièrement dangereux ;
car, en fonction de la définition ou non de NDEBUG, on obtient deux
programmes aux comportements différents : par exemple, un programme qui
plante quand NDEBUG n'est pas défini, mais qui marche quand NDEBUG est
défini. Ça peut être difficile à déboguer.

--
Richard
zwim
Le #19770481
Le Thu, 16 Jul 2009 07:37:28 +0200
Richard Delorme a écrit
Le 16/07/2009 02:52, -ed- a écrit :
On 15 juil, 18:50, Stéphane Zuckerman wrote:
Bonjour,

En effectuant quelques recherches sur le net, je suis tombé sur cet
article :

« Implementation of the memory-safe full ANSI-C compiler » (PLDI
2009).
(URL :http://www.informatik.uni-trier.de/~ley/db/conf/pldi/pldi2009.html)



Il semble que l'accès au document ne soit pas libre...




On peut trouver la thèse de l'auteur (traduite en anglais) ici :

http://www.taplas.org/~oiwa/thesis.pdf

J'ai parcouru très vite. Le principe consiste à utiliser un pointeur
"intelligent" qui détecte les principales erreurs (pointeur non
initialisé, accès hors tableau, etc.) pour, en général, terminer le
programme proprement. Ça évite certaines attaques, mais ça ne résoud pas
tous les problèmes.


De plus, je ne vois pas ce qui empêche en C standard, d'utiliser la
mémoire correctement et sans erreurs...



La bêtise humaine, malheureusement très répandu (je suis moi-même
contaminé). A noter que le programme de M. Iowa est un compilateur de C
standard, qui ne change rien au langage.



J'ai lu rapidement aussi, et même si les idées sont intéressantes
l'overhead est quand même très important de ce que j'ai pu voir.

Un facteur 2.5 à 3 au moins, dans la plupart des cas non triviaux ce
n'est pas rien.

Alors certes le C n'est pas très sûr (si on fait n'importe quoi avec)
mais il a au moins le mérite d'être rapide sans pour autant être aussi
impénétrable qu'un code en assembleur. Donc si ce compilateur lui
enlève cette qualité principale c'est quand même dommage.

L'auteur préconise pour palier à cela de réécrire entièrement le
compilateur en assembleur (ou un langage intermédiaire entre l'asm et
le C) en tenant compte des idées théoriques énoncées dans la thèse,
alors que jusqu'à présent il a écrit un préprocesseur qui sort du C et
qui est compilé par le compilo natif de la plateforme.

Je pense que si les idées sont bonnes, on trouvera des gens pour faire
cela (le premier compilo C++ était aussi un preprocesseur C, ce n'est
plus tout à fait le cas aujourd'hui).


--
zwim.
Rien n'est impossible que la mesure de la volonté humaine...
-ed-
Le #19771921
On 16 juil, 17:22, Richard Delorme
Le 16/07/2009 08:23, -ed- a écrit :

> #ifndef NDEBUG
> #define LIM_PTR(p,l) (p)[(l) -1]=0
> #else
> #define LIM_PTR(p,l)
> #endif

A mon avis, c'est ce genre de code qui est particulièrement dangereux ;
car, en fonction de la définition ou non de NDEBUG, on obtient deux
programmes aux comportements différents : par exemple, un programme qui
plante quand NDEBUG n'est pas défini, mais qui marche quand NDEBUG est
défini. Ça peut être difficile à déboguer.



Hum. Le but est de passer le jeu de tests en mode debug. Ensuite, en
production, plus rien de fâcheux de doit arriver si la couverture des
TU est correcte ...
Richard Delorme
Le #19773871
Le 17/07/2009 01:53, -ed- a écrit :
On 16 juil, 17:22, Richard Delorme
Le 16/07/2009 08:23, -ed- a écrit :

#ifndef NDEBUG
#define LIM_PTR(p,l) (p)[(l) -1]=0
#else
#define LIM_PTR(p,l)
#endif


A mon avis, c'est ce genre de code qui est particulièrement dangereux ;
car, en fonction de la définition ou non de NDEBUG, on obtient deux
programmes aux comportements différents : par exemple, un programme qui
plante quand NDEBUG n'est pas défini, mais qui marche quand NDEBUG est
défini. Ça peut être difficile à déboguer.



Hum. Le but est de passer le jeu de tests en mode debug.



Oui mais ton LIM_PTR ne teste rien, il fait une assignation. Donc en
mode débogage, les chaines sont toutes correctement terminée par ""
mais éventuellement tronquée, et pas en mode production.

--
Richard
-ed-
Le #19833601
On 17 juil, 11:55, Richard Delorme
Le 17/07/2009 01:53, -ed- a écrit :

> On 16 juil, 17:22, Richard Delorme >> Le 16/07/2009 08:23, -ed- a écrit :

>>> #ifndef NDEBUG
>>> #define LIM_PTR(p,l) (p)[(l) -1]=0
>>> #else
>>> #define LIM_PTR(p,l)
>>> #endif
>> A mon avis, c'est ce genre de code qui est particulièrement dangereu x ;
>> car, en fonction de la définition ou non de NDEBUG, on obtient deux
>> programmes aux comportements différents : par exemple, un programme qui
>> plante quand NDEBUG n'est pas défini, mais qui marche quand NDEBUG e st
>> défini. Ça peut être difficile à déboguer.

> Hum. Le but est de passer le jeu de tests en mode debug.

Oui mais ton LIM_PTR ne teste rien, il fait une assignation. Donc en



Bien sûr. C'est CHK_PTR() qui est 'actif'...

LIM_xxx() pose la limite et CHK_xxx() la teste. C'est difficile à
comprendre ? Il faut 3 pages de doc ?

mode débogage, les chaines sont toutes correctement terminée par ""
mais éventuellement tronquée, et pas en mode production.



Et ? Le but est de passer les tests (en mode debug) qui sont censés
couvrir les cas d'exploitation. Quel est le problème ?
Richard Delorme
Le #19834231
Le 26/07/2009 17:00, -ed- a écrit :
On 17 juil, 11:55, Richard Delorme
Le 17/07/2009 01:53, -ed- a écrit :

On 16 juil, 17:22, Richard Delorme
Le 16/07/2009 08:23, -ed- a écrit :
#ifndef NDEBUG
#define LIM_PTR(p,l) (p)[(l) -1]=0
#else
#define LIM_PTR(p,l)
#endif


A mon avis, c'est ce genre de code qui est particulièrement dangereux ;
car, en fonction de la définition ou non de NDEBUG, on obtient deux
programmes aux comportements différents : par exemple, un programme qui
plante quand NDEBUG n'est pas défini, mais qui marche quand NDEBUG est
défini. Ça peut être difficile à déboguer.


Hum. Le but est de passer le jeu de tests en mode debug.


Oui mais ton LIM_PTR ne teste rien, il fait une assignation. Donc en



Bien sûr. C'est CHK_PTR() qui est 'actif'...

LIM_xxx() pose la limite et CHK_xxx() la teste. C'est difficile à
comprendre ? Il faut 3 pages de doc ?



Sans doute, comme présenté ici je ne vois pas comment utiliser ton
LIM_xxx() ou ton CHK_xxx(), ou alors je vois des techniques plus
efficaces et lisibles.


mode débogage, les chaines sont toutes correctement terminée par ""
mais éventuellement tronquée, et pas en mode production.



Et ? Le but est de passer les tests (en mode debug) qui sont censés
couvrir les cas d'exploitation. Quel est le problème ?



Dans ce cas tu as un problème de terminologie. Le mode debug ne sert pas
à faire paser des tests, il sert, comme son nom l'indique, à déboguer.
Pour tes tests tu devrais utiliser un système de macros propres. Du genre :

#ifdef UNIT_TESTING
#define LIM_PTR(p,l) (p)[(l) -1]=0
#else
#define LIM_PTR(p,l)
#endif

--
Richard
-ed-
Le #19837531
On 26 juil, 19:49, Richard Delorme
Dans ce cas tu as un problème de terminologie. Le mode debug ne sert pa s
à faire paser des tests, il sert, comme son nom l'indique, à débogu er.
Pour tes tests tu devrais utiliser un système de macros propres. Du gen re :

#ifdef UNIT_TESTING
#define LIM_PTR(p,l) (p)[(l) -1]=0
#else
#define LIM_PTR(p,l)
#endif

--
Richard



Oui, pourquoi pas. J'ai été au plus simple. Chacun définit ses
stratégies de développement. Du moment que le résultat est fiable...

Pour ce qui est de l'utilisation, avec un pointeur sur un tableau, par
exemple ;

char *s = malloc(size);
LIM_PTR(s, size);

strcpy (s, "Hello world");
CHK_PTR(s, size);

Et voila ça a craqué...
Publicité
Poster une réponse
Anonyme