Niveau :      
Résumé : /proc/sys/fs/binfmt_misc/register

Exécution

Savez-vous qu'on peut rendre n'importe quel fichier exécutable sous linux ? Bien sûr il suffit de faire un chmod +x, mais le noyau risque de vous envoyer balader si le fichier n'est pas réellement exécutable.

Mais je parle ici de rendre exécutable n'importe quel fichier, un jar, un source en C, un MP3 ...

Mais comment quoi que donc !?

Pour exécuter un fichier, le noyau lit les premiers octets du fichier et vérifie qu'ils correspondent à un format binaire (binfmt) connu. Il existe un système pour ajouter des formats binaires à ceux déjà supportés dans le noyau (en gros les elf et les scripts). Il s'agit du format misc.

Pour savoir si ce format est supporté chez vous, ce qui est très probable, lancez la commande :

$ cat /proc/sys/fs/binfmt_misc/status

S'il n'est pas supporté, il faut charger le module et monter le répertoire :

$ modprobe binfmt_misc
$ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 

C capital

Maintenant supposons vous vouliez rendre les fichiers .c exécutables. Vous pouvez soit utiliser un de mes anciens articles ... soit créer un petit script qui sera appelé à chaque exécution d'un .c :

#!/bin/sh
# /usr/local/bin/ccexec
gcc -Wall -o /tmp/cscript.$$ "$1" && shift && /tmp/cscript.$$ "$@"
ret=$? ; rm -f /tmp/cscript.$$ ; exit $ret

Et de faire en sorte qu'il soit réellement appelé :

$ echo ':cfile:E::c::/usr/local/bin/ccexec:' > /proc/sys/fs/binfmt_misc/register

Hop un test :

#include <stdio.h>
// test.c
int main() {
  printf("Coucou\n");
  return 0;
}

Et on lance :

$ chmod +x test.c
$ ./test.c
> Coucou

Yeah !!!

G tout compris

Maintenant, passons à l'exécution d'un gzip. Plutôt que de reconnaître le fichier à son extension, ce qui est franchement faible comme méthode nous allons vraiment détecter le type de fichier.

Allons voir la spécification, un fichier gzip se reconnait à ses 2 premiers octets qui doivent valoir 0x1f et 0x8b :

$ echo ':gzip:M::\x1f\x8b::/bin/gunzip:' > /proc/sys/fs/binfmt_misc/register

Même méthode et ça marche. Notez qu'il est possible d'utiliser n'importe quel champs de bits grâce à une masque et une position de départ, mais seulement dans les 128 premiers octets du fichier.

Enfin, certaines distributions vont vous installer des choses un peu plus utiles comme l'exécution des jar avec java ou celle d'exécutable windows avec wine.

Et pour une spécification plus détaillée de ce qu'il lest possible de mettre dans la ligne d'enregistrement, direction la documentation

PS : pour supprimer l'entrée : echo -1 > /proc/sys/fs/binfmt_misc/cfile