Re: programmes déréférençant un point eur nul ...

Top Page

Reply to this message
Author: Francois-Xavier 'FiX' KOWALSKI
Date:  
To: Frédéric BOITEUX
CC: guilde
Subject: Re: programmes déréférençant un point eur nul ...
Frédéric BOITEUX wrote:

>Le Mon, 19 Aug 2002 17:25:42 +0200, Lucas Nussbaum <lucas@???> a écrit :
>
>
>
>>Pourquoi ne pas écrire une fonction :
>>
>>void sfree(void * ptr)
>>{
>>    if (ptr)
>>        free(ptr);
>>}

>>
>>Et ensuite, partout dans ton programme, remplacer free() par sfree() ?
>>
>>
>>
>
>En fait, le problème est plus vicieux : il ne s'agit pas simplement de free(NULL),
>mais bien d'algorithmes (foireux) où on autorise à lire le contenu d'un pointeur nul,
>du genre :
>
>while (*cp != 0) {
> bla bla;
>}
>


Il ne s'agit pas reellement d'un algorithme foireux, comme peu
apparaitre le de-referencement d'un simple octet null. En fait "it's not
a bug, it's a feature", qui vient de certains UNIX de souche BSD:
Quelques octets (en general une page entiere) sont "mappes" dans
l'espace de memoire virtuelle de tous les process avec les proprietes
suivantes:

    * En lecture seule,
    * Leur lecture est toujours "0",
    * Ils sont alignes avec n'importe quel type (forcement, en
      commencant a zero...),


Cette zone permet de comparer n'importe quel type de taille raisonable
(< taille d'une page memoire) avec son equivalent, rempli de zeros (NULL
scalaire) sans avoir a initialiser au prealable une structure avec des NULL.

>avec cp un pointeur pouvant valoir NULL !
>
>    Plus je regarde le problème, plus le test ou la relecture me semblent
>les seules solutions :-(((  .  Merci quand même,

>
>


Non, ce n'est pas la seule solution. Si ton programme est long (100.000+
lignes typiquement), il ne s'agit en fait meme pas d'une solution, car
il faut associer a cette recherche manuelle un tests de couverture de
code (type Gcov or PureCoverage).

La solution est dans le parametrage du noyau, quand il construit
l'espace d'adressage virtuel de tout process. Les executables HP-UX
presentent un flag dans leur header qui indiquent au noyau que le
programme se prepare a realiser des "NULL-DEREF". Le noyau "mappe" donc
la page "NULL" en bas de la memoire virtuelle du process, lors de exec(2).

Pour ce qui concerne Linux, je n'ai pas trouve de maniere evidente ce
flag dans les headers ELF... Il existe donc peut-etre sous forme de
parametre kernel direct (sysctl) ou alors peut-etre sous forme de patch.

Une alternative est d'utiliser un handler de SIGSEGV qui analyse le
*sigcontext, pour determiner si la faute de segmentation est due a un
NULL-DEREF & modifier les variables pour corriger le probleme
normallement. Evidement, il faut traiter les cas d'erreurs reelles comme
tels...

A+

FiX

--
François-Xavier 'FiX' KOWALSKI