forc3 a écrit 51 commentaires

  • [^] # Re: Et l'exemple qmail ?

    Posté par  . En réponse à la dépêche Exec Shield: protection contre les débordements de tampons. Évalué à 10.

    >> A priori, rien ne l'empêche.

    Si les stralloc.

    Qmail utilise des stralloc pour toute la gestion de ses chaines de caracteres, pour faire bref, les stralloc sont les g_string de la glib. C'est une structure qui contient un pointeur sur char et un unsigned int len correspondant a la taille du char * et un autre unsigned int a contenant la taille reelle allouee.

    a est toujours plus grand ou egal a len.

    Les stralloc permettent tres facilement de manipuler les chaines sans plus jamais se soucier de savoir si la taille allouee est assez grande.
    Le stralloc n'utilise pas de format et c'est _volontaire_.
    Les format sont tres souvent mal utilise, la doc est trop complexe, il suffit de les bannir. (cf format strings bug)

    De nos jour, faire des bugs de formats est inexcusable, disait quelqu'un ayant
    travaille serieusement la question. (marchant dans l'espace).
    Cependant ils sont encore mal utilises, de trop nombreux snprintf ne limitant pas la taille des arguments, ni d'appel verifiant la valeur de retour.

    Le man correspondant est pourtant clair, et donne meme un exemple de code le mettant en pratique... (pas encore suffisant... personne ne lit de nos jours !)

    Vsftpd utilise des stralloc cf fin du texte disponible sur son site dans:
    vsftpd-1.1.3/SECURITY/IMPLEMENTATION

    Site de qmail
    http://cr.yp.to/(...)

    -- ce qui suit n'est plus 'buffer overflow centric' mais est tout aussi important --
    Reimplementation GPL de outils Bernstein, pour la plupart public domain.
    http://www.fefe.de/libowfat/(...)
    La racine faut aussi le coup d'oeil.
    http://www.fefe.de/(...)

    Autre site utilisant du Bernstein like aka DJB ware.
    http://www.skarnet.org/(...)
    http://www.superscript.com/(...)
    http://www.smarden.org/pape/(...)

    Excellent outils disponibles mais pas assez mis en valeur.
    http://cr.yp.to/daemontools(...)
    http://www.smarden.org/runit(...)

    Ce n'est pas un hasard que depuis apache-1.3.26 une nouvelle option de ligne
    de lancement est apparue:
    -F run main process in foreground, for process supervisors.

    De plus tous ces softs utilisent un principe different de ce qu'est un daemon.
    Un daemon _ne_ doit _pas_ se detacher du son pere...
    Cela permet non seulement de monitorer ce daemon car un magnifique SIGCHLD va frapper a la porte du papa, signalant que son fils est mort :/
    Le papa peut rapidement le relancer.
    Si maintenant le pere peut faire la meme chose avec un autre fils (le frere de notre daemon) mais n'ayant que pour but dans sa vie de mettre par ecrit ce que
    son frere dit ... Vous obtenez une famille capable de tourner tout le temps.
    Vous donnez la capacite a ce frere de 'rotater' tout seul les logs, sans devoir 'killer' l'autre frere. Si vous lui ajouter en plus la possibilite de gerer lui meme le timestamp, et si vous lui donnez en plus la possibilite d'executer une action avant de 'rotater' vous obtenez une famille formidable...

    A la poubelle rotatelogs qui continue a faire des scripts shell pour killer les daemons. Un daemons est cense rester actif tout le temps.
    Ce n'est pas son boulot de faire appel a toute ces actions a gettimeofday() pour coller un timestamp. Laissons ce travail a un processus dedie, lui aussi monitore.

    De plus ce fameux timestamp, qui est toujours different entre tous les daemons... Et le fameux syslog() de la glibc qui a la grande idee de tronquer a l'annee. Tres pratique pour refaire des requetes SQL derriere contenant le temps, car notre timestamp lui necessite l'annee... Du coup notre parseur de log a lui aussi besoin d'appeler gettimeofday() sur toutes les lignes qu'il recoit. Sans compter qu'il faut le faire en temps reel car sinon il faut imaginer ce qu'il se passerait au date proche de la st sylvestre. Le parseur de log est en 2004 alors que les logs syslog datent de la semaine precedente.

    Si vraiment vous pensez que syslog est viable (mdr...) utiliser www.smarden.org/socklog, avec multilog.

    Maintenant que notre daemon est monitore, que son frere s'occupe de logguer son activite, et que pour passer des ordres il suffit de commandes archi-simple, sans devoir se soucier d'un quelconque PID.
    (Normal le pere, lui, il est au courant du numero de son fils ...)

    De plus les fils ne sont pas jumeaux, il peuvent tout a fait, et c'est recommande avoir des identites differentes... Un processus de log independant, monitore, qui rotate tout seul, qui peut vautrer sans bloquer le daemon, mais qui sera relancer aussitot. (Au passage il faut y aller pour faire tomber multilog)

    Tres tres utile via des directive CustomLog de Apache, utilisant des pipes

    On vire le timestamp car on va utiliser celui de multilog:
    LogFormat "%h %u \"%r\" %>s %b" multilog

    On fait 5 paquets max de log de environ 1M max, on log sous l'id log et non plus apache... ou root (;p mdr)
    CustomLog "| /usr/local/bin/setuidgid log /usr/local/bin/multilog t s999999 n5 /var/log/apache/access" multilog

    Voila un apache pres a tourner 24/24 sans jamais devoir se soucier d'avoir une tache cron qui appelle bien rotatelog qui va bien faire 1 script shell qui va bien parcourir la liste des pid en utilisant ps qui va bien faire un kill sur apache apres ... (humm que du bonheur).

    Pour terminer, il faut separer les processus, il ne faut pas faire faire a votre daemon des choses qui sont faisables par d'autre programmes.

    Utiliser des 'stralloc' like, bannissez les formats, utiliser toujours des filedescriptor, minimiser les appels a malloc(), utiliser alloca() quand vous le pouvez, ne forker pas au demarrage. Et aller lire le code source de qmail et de vsftpd.

    Et enfin:
    Reclamez l'implementation d'un syscall unlink() utilisant un fd et non plus un const char * (;p)