Recherche du nom du paquet d’envoi exécutable dans un hook netfilter

J’écris un module de kernel qui utilise un hook netfilter pour filtrer les paquets TCP et doit trouver le chemin d’access à l’exécutable qui envoie les paquets. Jusqu’ici, j’ai utilisé l’approche suivante, mais elle imprime des noms apparemment sans rapport avec les exécutables utilisés ( / usr / lib / firefox / firefox , usr / bin / telnet.netkit et / usr / bin / wget ).

pid_t pid = current->pid; struct path path; char buff[BUFF_LEN]; snprintf (buff, BUFF_LEN, "/proc/%d/exe", pid); if(!kern_path(buff, LOOKUP_FOLLOW, &path)) { struct dentry* procEntry = path.dentry; printk("Process: %s\n", procEntry->d_name.name); printk("Parent: %s\n", procEntry->d_parent->d_name.name); } 

Sortie du journal du kernel: entrez la description de l'image ici

Cela ressemble à un travail de qualité médiocre dans un collège et j’ai la nette impression que quelque chose du genre a déjà paru ici.

Votre code s’exécutera probablement à partir d’un contexte d’interruption, c’est-à-dire qu’un thread aléatoire sera interrompu pour traiter des paquets et «current» sera un pointeur sur ledit thread aléatoire. Cela devrait être facile à vérifier, par exemple en obtenant une trace – ce qui est réalisable avec WARN_ONCE et similaire.

Rechercher un nom de fichier exécutable en passant par procfs est étrangement mauvais. procfs doit faire plus de travail et finit par avoir access à ce qui est effectivement actuel. Pour aggraver les choses, vous ne parvenez pas à mettre le chemin trouvé, donc vous perdez des ressources. Si ce code s’exécute effectivement à partir d’un gestionnaire d’interruption, le résultat n’est pas seulement absurde, mais ne peut pas être obtenu en toute sécurité avec cette méthode en raison du potentiel de veille.

Même si vous obteniez le “bon” nom de l’exécutable, l’assignation entière est de la merde. Un processus peut modifier l’exécution d’un autre de plusieurs manières. évitant ainsi efficacement tout filtre en place. Il est intéressant de noter qu’il existe un moyen de changer simplement le nom de votre processus en autre chose sans rien exécuter, ce qui invalide une fois de plus le concept.

Le mieux que vous puissiez faire est de filtrer par informations d’identification, mais elles ne sont pas spécifiques à un processus. En principe, vous pouvez append des étiquettes selinux aux fichiers et les filtrer, mais là encore, c’est faible.

En bref, la mission est des conneries.