简体   繁体   中英

How would one go about generating “artificial” interrupts in the Linux Kernel?

I've read the answer here: Trigger Kernel Interrupt Handler: How? and it's a good one, but not quite what I need.

I'm microbenchmarking the RNG functions in regards to processing interrupts, so I need a good way to artificially and repeatably generate interrupts. For example, I could redirect something into a Procfs interface that generates 300 interrupts or something like that.

Is it as easy as running some kind of function in the kernel that generates an interrupt?

Is there some kind of interrupt that does not actually do "Anything", but still goes through the entire interrupt handler path? I realize I could just type keys or something like that but that's not really repeatable and scriptable for research purposes.

I'm working with the x86 architecture.

Here is a potential solution that generates fake keyboard interrupts, from the PoV of the kernel there's no way to tell that these interrupts aren't real.

Only interrupt handlers installed with SA_SAMPLE_RANDOM will generate entropy, this eliminates syscalls for this purpose. However keyboard interrupts do generate entropy.

I have not tested the following code, and can't offer any guarantees, but I believe that it should work if ran as part of a kernel module.

The following snippet of code shows how to forcefully inject a key into the keyboard controller's buffer. This will not work if a real PS/2 keyboard (or USB keyboard with Legacy USB support in BIOS) is not plugged in. This code was copied from a SMM keylogger article on Phrack

The code is in x86 assembly, you can wrap it in an inline assembly block asm(""); if you write your kernel module in 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

Then to generate the keyboard interrupt do :

int 33

Interrupt 33 is typically the PS/2 keyboard. This will cause Linux to handle the keyboard interrupt, read our fake scancode, and generate some randomness for you. You will want to call this in a loop, but be careful, Linux generates randomness based in part on the interval between two interrupts, if you force interrupts at fixed intervals, you will get very little entropy out of this method.

Note that it should also work if you do just asm("int $33") without running the first part of the code, but that might confuse the kernel.

Just start a high-resolution timer:

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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM