Greboca  

Suport technique et veille technologique

Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.

C’est alors la barrière de la prise en main qui fait peur, et pourtant...

Les logiciels libres

L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.

Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.

Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.

Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.

LinuxFr.org : les journaux  -  Comment rendre le shebang plus festif

 -  Octobre 2019 - 

Sommaire

Suite à une discussion avec un collègue, je me suis lancé dans un correctif du noyau pour remplacer le shebang (#!) par un caractère bien plus adapté : 🍻. Il faut savoir que le shebang est lu par le noyau. Quand on demande d’exécuter un fichier à ce dernier, il essaye toutes les méthodes qu’il connait (script, ELF) jusqu’à ce qu’il y en ait une qui fonctionne. Une de ces méthodes est le script où il exécute le binaire donné par le shebang et passe le script en paramètre.

Mise en place

Compilation d’un noyau vanilla

Déjà, la première chose, c’est de vérifier que j’arrive encore à compiler un noyau. Et surtout que j’arrive à l’amorcer. Comme j’ai un pressentiment que ça peut poser problème dans l’amorçage d’un système classique, je préfère utiliser une machine virtuelle.

Donc, première étape, make oldconfig et make -j16. Bon, depuis la dernière fois que j’ai compilé un noyau, il y a des modules signés. Comme je ne compte pas utiliser de module, je désactive la fonctionnalité de signature avec make menuconfig dans le menu « Enable loadable module support » et les clefs dans « security options → Trusted keys ». Bien, ça compile.

Deuxième étape comment compiler un noyau sans l’installer sur le système (ce que 98,7 % des tutoriels sur le sujet font) ? Après quelques recherches, il suffit de faire un make bzImage. Le noyau généré se trouve dans arch/x86/boot/bzImage.

QEMU permet d’amorcer directement un noyau sans devoir passer par un gestionnaire d’amorçage (bootloader). C’est pratique, ça va me simplifier mes tests. Je peux donc lancer la commande suivante :

qemu-system-x86_64 -kernel arch/x86/boot/bzImage

Et ça démarre, avec un kernel panic parce qu’il ne trouve pas le système de fichiers racine (rootfs), ce qui est plutôt rassurant vu que je ne lui en ai pas donné.

QEMU permet d’utiliser un initrd aussi, mais vu ma configuration assez simple, je préfère m’en passer. Et comme je n’oublie jamais rien, je me dis que je compilerai les modules dont j’ai besoin en statique.

Amorçage avec BusyBox

Donc, il me faut un programme d’initialisation, de préférence simple et sans script Shell. Il me faut aussi un système minimaliste avec un Shell et quelques binaires comme ls et cat pour pouvoir déboguer. Le job parfait pour BusyBox. Donc, je crée une image qcow2 avec virt-make-fs, qui contient BusyBox et un script shell basique pour vérifier que ça fonctionne, et un lien symbolique pour avoir un /bin/sh.

cat > hostdir/shebang.sh <

N. D. M. : commandes modifiées suites aux remarques dans les commentaires.

Je peux donc amorcer avec :

qemu-system-x86_64 -kernel  arch/x86/boot/bzImage -append "root=/dev/sda1 init=/busybox sh" -hda hostimg.qcow2

Attention à bien mettre le sh à la fin de la ligne d’amorçage, sinon BusyBox affiche l’aide et quitte, et le noyau panique parce que le processus numéro 1 (PID 1) est parti.

Après quelques essais pour trouver les modules à compiler en statique pour avoir le pilote pour le disque (et le pilote pour ext4 que j’avais oublié), j’ai donc un système qui démarre avec un shell et mon script de test fonctionne (mais ce n’est pas surprenant).

Correctif

Je décide d’abord de modifier un seul caractère du shebang pour vérifier que c’est bien possible, mon shebang sera donc ##. Je trouve le fichier où le shebang est défini grâce à Google : fs/binfmt_script.c. Pratique, on dirait qu’il suffit de changer un caractère. Je fais donc la modification suivante :

--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -39,7 +39,7 @@ static int load_script(struct linux_binprm *bprm)
        int retval;

        /* Not ours to exec if we don't start with "#!". */
-       if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
+       if ((bprm->buf[0] != '#') || (bprm->buf[1] != '#'))
                return -ENOEXEC;

        /*

Et je peux tester avec un nouveau script qui comment par ##/bin/sh. Il fonctionne bien et un script avec un #!/bin/sh renvoie une erreur. Je peux donc passer à l’étape suivante, un shebang sur quatre caractères, vu que l’émoji prend quatre octets en UFT-8 : f0 9f 8d bb. Comme il y a des opérations sur le tampon qui contient la ligne qui sont faites en décalant le démarrage en se basant sur la longueur de deux octets, on remplace ça par un quatre :

--- a/fs/binfmt_script.c
+++ b/fs/binfmt_script.c
@@ -39,7 +39,8 @@ static int load_script(struct linux_binprm *bprm)
        int retval;

        /* Not ours to exec if we don't start with "#!". */
-       if ((bprm->buf[0] != '#') || (bprm->buf[1] != '#'))
+    // 🍻 f0 9f 8d bb
+       if ((bprm->buf[0] != '\xf0') || (bprm->buf[1] != '\x9f') || (bprm->buf[2] != '\x8d' || bprm->buf[3] != '\xbb'))
                return -ENOEXEC;

        /*
@@ -73,7 +74,7 @@ static int load_script(struct linux_binprm *bprm)
        buf_end = bprm->buf + sizeof(bprm->buf) - 1;
        cp = strnchr(bprm->buf, sizeof(bprm->buf), '\n');
        if (!cp) {
-               cp = next_non_spacetab(bprm->buf + 2, buf_end);
+               cp = next_non_spacetab(bprm->buf + 4, buf_end);
                if (!cp)
                        return -ENOEXEC; /* Entire buf is spaces/tabs */
                /*
@@ -93,7 +94,7 @@ static int load_script(struct linux_binprm *bprm)
                else
                        break;
        }
-       for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
+       for (cp = bprm->buf+4; (*cp == ' ') || (*cp == '\t'); cp++);
        if (*cp == '\0')
                return -ENOEXEC; /* No interpreter name found */
        i_name = cp;

On recompile, relance la machine virtuelle et l’on peut tester avec un script qui contient le nouveau shebang.

Vous pouvez retrouver les deux correctifs ici : https://github.com/claudex/linux-shebang/commits/master.

Et ça marche ?

Premièrement, le sh de BusyBox (et sans doute tous les shells) n’aime pas que la première ligne ne commence pas par #. On se retrouve avec l’erreur « ./beerbang.sh: line 1: 🍻/bin/sh not found. » car, vu que la ligne ne commence pas par #, il ne la traite pas comme un commentaire et donc essaye de l’exécuter et, évidemment, il ne trouve pas de commande pareille à exécuter. Mais il exécute le reste du script sans problème.

Screenshot busybox

Le contenu du beerbang.sh :

🍻/bin/sh

echo "beers!"

Un autre point, mais qui relève plus du détail. Comme on fait de l’Unicode, il faudrait normalement canoniser la séquence de caractères, car il y a peut‐être d’autres façons de l’écrire. Je laisse l’exercice au lecteur.

Et l’intérêt de la chose dans tout ça ?

Strictement aucun !

Commentaires : voir le flux atom ouvrir dans le navigateur

par Xavier Claude

LinuxFr.org : les journaux

LinuxFr.org : Journaux

firefox, nouvelle fenêtre dans une session isolée

 -  15 avril - 

Les fenêtres de navigation privées de firefox partagent leurs cookies de session or je souhaitais avoir des fenêtres de navigation isolées, (qui ne (...)


Pretendo tente de déprogrammer l'obsolescence des consoles Nintendo

 -  9 avril - 

Ah Nal,Gros N vient de faire un gros doigt aux utilisateurs de ses consoles 3DS et Wii U en annonçant la fermeture des services en ligne pour (...)


[Trolldi] Vulgarisation sur l'IA pour décideur pressé

 -  5 avril - 

Cher 'Nal,Je fais un article-marque-page sur un post tout frais de Ploum où il est question d'un fantasme vieux comme le Talmud avec le Golem. (...)


Super Marian and Robin: les roms en collant

 -  3 avril - 

Bonjour Nal,Je t'écris pour te proposer de tester mon nouveau jeu: Super Marian and Robin.Il s'agit d'un jeu de plateformes pour un ou deux (...)


Le roi est mort, vive le roi ! Les alternatives de Redis sont là

 -  3 avril - 

Bonjour Nal !Après le changement de licence de Redis, ce qui devait arriver arriva, et des alternatives libres apparaissent.Tout d'abord, on a (...)