Générer une erreur de segmentation à partir d’un appel système personnalisé

Je fais un copy_to_user() depuis un appel système.

Comment puis-je le faire pour générer un segfault ou un sigbus en cas d’erreur, comme si l’espace utilisateur essayait d’accéder à la même mémoire?

Eh bien, en général, vous ne pouvez pas. Sauf si vous prévoyez de réécrire le kernel.

Lorsque le kernel accède aux adresses en mode utilisateur, il utilise un formulaire sécurisé, généralement copy_from_user , copy_to_user , get_user , … – comme vous l’avez mentionné. Ces macros ont une valeur de retour que le kernel vérifie et, dans la plupart des cas, -EFAULT .

Ensuite, vient généralement libc et ajuste la valeur de retour pour qu’elle corresponde à la page de manuel – ce qui signifie qu’elle définit errno si le résultat est erroné (selon l’appel système appelé).

Par exemple, un extrait de code commun dans le kernel est le suivant:

 if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t)))) return -EFAULT; 

(extrait de l’implémentation de sendfile64 syscall à fs / read_write.c)

Comme vous le voyez, lorsque le kernel ne parvient pas à lire depuis le mode utilisateur, il retourne -EFAULT .

Étant donné qu’il est possible de transmettre plus d’un pointeur à certains appels système, il peut être impossible de déterminer lequel a provoqué l’ -EFAULT . Il n’y a donc pas de méthode usermode générique pour envoyer des SIGSEGV lors d’un access mémoire invalide vérifié pour le compte du kernel.


Si, cependant, vous écrivez vous-même un kernel syscall, et que vous voulez déclencher un signal, ce n’est pas difficile du tout. Je n’ai pas trop creusé dans le kernel, mais ce que vous recherchez est d’appeler quelque chose parmi les lignes de send_sig_info (ou une autre fonction appropriée dans kernel / signal.c).