Comment pourrait-on générer des interruptions «artificielles» dans le kernel Linux?

J’ai lu la réponse ici: Trigger Kernel Interrupt Handler: Comment? et c’est un bon, mais pas tout à fait ce dont j’ai besoin.

Je fais de la micro-parsing comparative des fonctions de RNG en ce qui concerne le traitement des interruptions. J’ai donc besoin d’un bon moyen de générer des interruptions de manière artificielle et répétée . Par exemple, je pourrais redirect quelque chose dans une interface Procfs qui génère 300 interruptions ou quelque chose comme ça.

Est-ce aussi simple que d’exécuter une sorte de fonction dans le kernel qui génère une interruption?

Existe-t-il une sorte d’interruption qui ne fait pas “Quelque chose”, mais passe tout le chemin du gestionnaire d’interruptions? Je réalise que je pourrais simplement taper des clés ou quelque chose du genre, mais ce n’est pas vraiment reproductible et scriptable à des fins de recherche.

Je travaille avec l’architecture x86.

Voici une solution potentielle qui génère de fausses interruptions au clavier. À partir de la PoV du kernel, il n’ya aucun moyen de savoir que ces interruptions ne sont pas réelles.

Seuls les gestionnaires d’interruptions installés avec SA_SAMPLE_RANDOM généreront une entropie, ce qui élimine les appels système à cette fin. Cependant, les interruptions du clavier génèrent une entropie.

Je n’ai pas testé le code suivant et je ne peux offrir aucune garantie, mais je pense qu’il devrait fonctionner s’il était exécuté dans le cadre d’un module de kernel.

L’extrait de code suivant montre comment injecter avec force une clé dans la mémoire tampon du contrôleur de clavier. Cela ne fonctionnera pas si un vrai clavier PS / 2 (ou un clavier USB avec prise en charge de Legacy USB dans le BIOS) n’est pas branché. Ce code a été copié à partir d’un article du keylogger SMM sur Phrack.

Le code est en assemblage x86, vous pouvez l’envelopper dans un bloc d’assemblage en ligne asm(""); si vous écrivez votre module de kernel en C.

 ; write command byte 0xD2 to command port 0x64 ; to re-inject intercepted scan code into keyboard controller buffer ; so that OS keyboard interrupt can read and display it later mov al, 0xd2 out 0x64, al ; wait until keyboard controller is ready to read _wait: in al, 0x64 test al, 0x2 jnz _wait ; re-inject scan code for the key '1' mov ax, 1 out 0x60, al 

Ensuite, pour générer l’interruption du clavier, procédez comme suit:

 int 33 

L’interruption 33 correspond généralement au clavier PS / 2. Cela obligera Linux à gérer l’interruption du clavier, à lire notre faux scancode et à générer un caractère aléatoire pour vous. Vous voudrez appeler ceci en boucle, mais soyez prudent, Linux génère un caractère aléatoire basé en partie sur l’intervalle entre deux interruptions. Si vous forcez les interruptions à des intervalles fixes, vous obtiendrez très peu d’entropie avec cette méthode.

Notez que cela devrait également fonctionner si vous faites simplement asm("int $33") sans exécuter la première partie du code, mais cela pourrait confondre le kernel.

Il suffit de démarrer un minuteur haute résolution:

 struct hrtimer timer; hrtimer_init(&timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); timer.function = my_little_timer; hrtimer_start(&timer, ktime_set(0, 500000000 /* ns */), HRTIMER_MODE_REL); ... hrtimer_cancel(&timer); ... enum hrtimer_restart my_little_timer(struct hrtimer *timer) { // either: hrtimer_forward_now(timer, ktime_set(...)); return HRTIMER_RESTART; // or: return HRTIMER_NORESTART; }