Зонд ядра не вставлен для функции system_call

Я могу использовать kprobe механизм для прикрепления обработчиков, используя следующий пример кода:

#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/kallsyms.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/kprobes.h> 

static struct kprobe kp; 

int Pre_Handler(struct kprobe *p, struct pt_regs *regs){
    printk("pre_handler\n");
    return 0;
}

void Post_Handler(struct kprobe *p, struct pt_regs *regs, unsigned long flags) {
    printk("post_handler\n");
} 

int __init init (void) {
    kp.pre_handler = Pre_Handler;
    kp.post_handler = Post_Handler;
    kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("sys_fork"); 
    printk("%d\n", register_kprobe(&kp)); 
    return 0;
}

void __exit cleanup(void) {
    unregister_kprobe(&kp); 
}

MODULE_LICENSE("GPL");   
module_init(init);
module_exit(cleanup); 

Однако, похоже, что не все подпрограммы ядра могут быть отслежены таким образом. Я пытался прикрепить обработчики к system_call чтобы они вызывались при выполнении любого системного вызова со следующим изменением:

kp.addr = (kprobe_opcode_t *)kallsyms_lookup_name("system_call"); 

И зонды не вставлены. dmesg показывает, что register_kprobe возвращает -22, что -EINVAL, Почему эту функцию невозможно отследить? Можно ли подключить обработчик kprobe перед отправкой какого-либо системного вызова?

$ uname -r
3.8.0-29-generic

1 ответ

Решение

system_call защищен от kprobes, невозможно проверить функцию system_call. Я думаю, что у нас нет никакой полезной информации, которую вы можете получить, прежде чем будет вызван какой-либо реальный системный вызов. например, если вы видите функцию system_call:

    RING0_INT_FRAME                 # can't unwind into user space anyway
    ASM_CLAC
    pushl_cfi %eax                  # save orig_eax
    SAVE_ALL
    GET_THREAD_INFO(%ebp)
                                    # system call tracing in operation / emulation
    testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
    jnz syscall_trace_entry
    cmpl $(NR_syscalls), %eax
    jae syscall_badsys
    syscall_call:
    call *sys_call_table(,%eax,4)

Есть несколько инструкций, прежде чем ваш фактический системный вызов будет вызван. да, я не уверен, если вам нужна какая-либо информация в этих инструкциях.

Другие вопросы по тегам