init_module(2)

NOM
init_module, finit_module - Charger un module de noyau

BIBLIOTHÈQUE
Bibliothèque C standard (libc, -lc)

SYNOPSIS
#include <linux/module.h>    /* Définition des constantes                                            MODULE_* */
#include <sys/syscall.h>     /* Définition des constantes                                            SYS_* */
#include <unistd.h>

int syscall(SYS_init_module, void module_image[.size], unsigned long size,
            const char *param_values);
int syscall(SYS_finit_module, int fd,
            const char *param_values, int flags);

Note : la glibc ne fournit pas de fonction autour de cet appel système, l'utilisation de syscall(2) est requise.

DESCRIPTION
init_module() charge une image ELF dans l'espace du noyau, réalise toutes les réallocations de symboles nécessaires, initialise les paramètres du module aux valeurs fournies par l'appelant et exécute ensuite la fonction init du module. Cet appel système nécessite des droits.

The module_image argument points to a buffer containing the binary image to be loaded; size specifies the size of that buffer. The module image should be a valid ELF image, built for the running kernel.

L'argument param_values est une chaîne contenant une liste de valeurs, séparées par des espaces, de paramètres du module (définis dans le module en utilisant module_param() et module_param_array()). Le noyau analyse cette chaîne et initialise les paramètres indiqués. Toutes les spécifications de paramètres sont de la forme :

nom[ =valeur [,valeur...]]

Le paramètre nom est un de ceux définis dans le module en utilisant module_param() (consultez le fichier include/linux/moduleparam.h dans les sources du noyau Linux). Le paramètre valeur est facultatif pour les paramètres de type bool et invbool. Les valeurs des paramètres de tableau sont indiquées en liste, séparées par des virgules.

  finit_module()
L'appel système finit_module() est comme init_module(), mais lit le module à charger à partir du descripteur de fichier fd. Il est utile quand l'authenticité d'un module du noyau peut être déterminée par son emplacement sur le système de fichiers. Dans les cas où c'est possible, la complication induite par la vérification cryptographique de modules signés pour déterminer leur authenticité peut être évitée. L'argument param_values est comme pour init_module().

L'argument flags modifie l'opération de finit_module(). C'est un masque OU bit à bit de zéro ou plusieurs des attributs suivants.

MODULE_INIT_IGNORE_MODVERSIONS
    Ignorer les hachages de version de symbole.

MODULE_INIT_IGNORE_VERMAGIC
    Ignorer la version magique du noyau.

MODULE_INIT_COMPRESSED_FILE (depuis Linux 5.17
    Utilisation de la décompression du module interne du noyau.

Certaines vérifications de sécurité sont construites dans un module pour s'assurer qu'il correspond au noyau sur lequel il est chargé. Ces vérifications sont enregistrées quand le module est construit et utilisées quand le module est chargé. D'abord, le module enregistre une chaîne « vermagic » contenant le numéro de version du noyau et les fonctionnalités principales (comme le type de microprocesseur). Ensuite, si le module a été construit avec l'option de configuration CONFIG_MODVERSIONS activée, un hachage de version est enregistré pour chaque symbole que le module utilise. Ce hachage est basé sur les types de l'argument et la valeur de retour pour la fonction nommée par le symbole. Dans ce cas, le numéro de version du noyau dans la chaîne « vermagic » est ignoré, car les hachages de version de symbole sont supposés être suffisamment fiables.

L'utilisation de l'attribut MODULE_INIT_IGNORE_VERMAGIC indique que la chaîne « vermagic » est à ignorer, et l'attribut MODULE_INIT_IGNORE_MODVERSIONS indique que les hachages de version de symbole sont à ignorer. Si le noyau est construit pour permettre le chargement forcé (c'est-à-dire configuré avec CONFIG_MODULE_FORCE_LOAD), alors le chargement continuera, sinon il échouera avec ENOEXEC comme attendu pour les modules malformés.

Si le noyau a été construit avec CONFIG_MODULE_DECOMPRESS, la fonctionnalité de décompression interne au noyau peut être utilisée. Le code dans l'espace utilisateur peut vérifier si le noyau prend en charge la décompression en en lisant l'attribut /sys/module/compression. Si le noyau prend en charge la décompression, le fichier compressé peut être directement fourni à finit_module() en utilisant le drapeau MODULE_INIT_COMPRESSED_FILE. Le décompresseur de module interne au noyau gère les algorithmes de compression suivants :

    -   gzip (depuis Linux 5.17)
    -   xz (depuis Linux 5.17)
    -   zstd (depuis Linux 6.2)

Le noyau n'implémente qu'une seule méthode de décompression. Elle est sélectionnée pendant la génération du module, selon la méthode de compression choisie dans la configuration du noyau.

VALEUR RENVOYÉE
Ces appels système renvoient 0 en cas de succès, ou -1 en cas d'échec, auquel cas errno est positionné pour indiquer l'erreur.

ERREURS

EBADMSG (depuis Linux 3.7)
    La signature du module est mal formatée.

EBUSY
    Délai dépassé en essayant de résoudre une référence de symbole par ce module.

EFAULT
    Un argument d'adresse faisait référence à un emplacement en dehors de l'espace d'adressage accessible du processus.

ENOKEY (depuis Linux 3.7
    La signature du module est incorrecte ou le noyau n'a pas de clef pour ce module. Cette erreur n'est renvoyée que si le noyau a été configuré avec CONFIG_MODULE_SIG_FORCE. Si le noyau n'a pas été configuré avec cette option, alors un module incorrect ou non signé corrompt simplement le noyau.

ENOMEM
    Plus assez de mémoire.

EPERM
    L'appelant n'avait pas les droits (n'avait pas la capacité CAP_SYS_MODULE), ou le chargement de module est désactivé (consultez /proc/sys/kernel/modules_disabled dans proc(5)).

Les erreurs supplémentaires suivantes peuvent survenir pour init_module().

EEXIST
    Un module de ce nom est déjà chargé.

EINVAL
    param_values est incorrect, ou certaines parties de l'image ELF de module_image contiennent des incohérences.

ENOEXEC
    L'image binaire fournie dans module_image n'est pas une image ELF, ou est une image ELF incorrecte ou pour une autre architecture.

Les erreurs supplémentaires suivantes peuvent survenir pour finit_module().

EBADF
    Le fichier indiqué par fd n'est pas ouvert en lecture.

EFBIG
    Le fichier indiqué par fd est trop gros.

EINVAL
    flags n'est pas correct.

EINVAL
    Les vérifications de propreté du décompresseur ont échoué pendant le chargement d'un module compressé avec le positionnement du drapeau MODULE_INIT_COMPRESSED_FILE.

ENOEXEC
    fd ne fait pas référence à un fichier ouvert.

EOPNOTSUPP (depuis Linux 5.17)
    Le drapeau MODULE_INIT_COMPRESSED_FILE est positionné pour charger un module compressé et le noyau a été construit sans CONFIG_MODULE_DECOMPRESS.

ETXTBSY (depuis Linux 4.7)
    Le fichier indiqué par fd est ouvert en lecture et écriture.

En plus des erreurs précédentes, si la fonction init du module est exécutée et renvoie une erreur, alors init_module() ou finit_module() échoue et errno est définie à la valeur renvoyée par la fonction init.

STANDARDS
Linux.

HISTORIQUE

finit_module()
    Linux 3.8.

L'appel système init_module() n'est pas pris en charge par la glibc. Il n'est pas déclaré dans les en-têtes de la glibc mais, par un caprice de l'histoire, les versions de la glibc antérieures à la glibc 2.23 fournissaient une interface binaire pour cet appel système. Ainsi, avant la glibc 2.23, il suffit de déclarer manuellement l'interface dans votre code pour utiliser cet appel système. Sinon, vous pouvez l'invoquer en utilisant syscall(2).

  Linux 2.4 et antérieurs
Dans Linux 2.4 et antérieurs, l'appel système init_module() était assez différent :

#include <linux/module.h>

int init_module(const char *name, struct module *image);

(les applications en espace utilisateur peuvent détecter la versions de init_module() disponible en appelant query_module() ; ce dernier appel échoue avec l'erreur ENOSYS à partir de Linux 2.6)

L'ancienne version de l'appel système charge l'image de module réallouée pointée par image dans l'espace du noyau et exécute la fonction init du module. L'appelant doit fournir l'image réallouée (depuis Linux 2.6, l'appel système init_module() s'occupe de la réallocation).

L'image du module commence avec une structure module suivie par du code et des données appropriés. Depuis Linux 2.2, la structure module est définie comme suit :

    struct module {
        unsigned long         size_of_struct;
        struct module        *next;
        const char           *name;
        unsigned long         size;
        long                  usecount;
        unsigned long         flags;
        unsigned int          nsyms;
        unsigned int          ndeps;
        struct module_symbol *syms;
        struct module_ref    *deps;
        struct module_ref    *refs;
        typeof(int (void))   *init;
        typeof(void (void))  *cleanup;
        const struct exception_table_entry *ex_table_start;
        const struct exception_table_entry *ex_table_end;
    #ifdef __alpha__
        unsigned long gp;
    #endif
    };

On s'attend à ce que tous les champs pointeurs, à l'exception de next et refs, pointent vers l'intérieur du corps du module et qu'ils puissent être initialisés de manière appropriée pour l'espace noyau, c'est-à-dire relogés avec le reste du module.

NOTES
Des renseignements concernant les modules chargés sont disponibles dans /proc/modules et dans les arborescences de fichiers des sous-répertoires par module sous /sys/module.

Consultez le fichier include/linux/module.h dans les sources du noyau Linux pour obtenir des renseignements de fond utiles.

VOIR AUSSI
create_module(2), delete_module(2), query_module(2), lsmod(8), modprobe(8)

TRADUCTION
La traduction française de cette page de manuel a été créée par Christophe Blaess <https://www.blaess.fr/christophe/>, Stéphan Rafin <stephan.rafin@laposte.net>, Thierry Vignaud <tvignaud@mandriva.com>, François Micaux, Alain Portal <aportal@univ-montp2.fr>, Jean-Philippe Guérard <fevrier@tigreraye.org>, Jean-Luc Coulon (f5ibh) <jean-luc.coulon@wanadoo.fr>, Julien Cristau <jcristau@debian.org>, Thomas Huriaux <thomas.huriaux@gmail.com>, Nicolas François <nicolas.francois@centraliens.net>, Florentin Duneau <fduneau@gmail.com>, Simon Paillard <simon.paillard@resel.enst-bretagne.fr>, Denis Barbier <barbier@debian.org>, David Prévot <david@tilapin.org> et Jean-Philippe MENGUAL <jpmengual@debian.org>

Cette traduction est une documentation libre ; veuillez vous reporter à la GNU General Public License version 3 (https://www.gnu.org/licenses/gpl-3.0.html) concernant les conditions de copie et de distribution. Il n'y a aucune RESPONSABILITÉ LÉGALE.

Si vous découvrez un bogue dans la traduction de cette page de manuel, veuillez envoyer un message à debian-l10n-french@lists.debian.org.