2014-11-14 17 views
8

Ho scritto del codice del kernel Linux, che causa un errore di runtime, e riporta linux unable to handle kernel paging request at ffffffff00000010.Qual è l'errore di "linux non è in grado di gestire la richiesta di paging del kernel su ffffffff00000010"?

È solo un codice per agganciare la chiamata di sistema open alla programmazione del kernel Linux.

Il codice è riportato di seguito:

#include <linux/kernel.h> 
#include <linux/init.h> 
#include <linux/module.h> 
#include <asm/uaccess.h> 
#include <asm/fcntl.h> 
#include <asm/unistd.h> 
#include <asm/ia32_unistd.h> 
#include <asm/msr.h> 
unsigned long *sys_table = NULL; 
asmlinkage long (*old_open) (const char __user *filename, int flags, umode_t mode); 
static void *memmem(const void *haystack, size_t haystack_len, 
      const void *needle, size_t needle_len); 
#define dbg(format,args...) \ 
    printk("intercept: function:%s-L%d: "format, __FUNCTION__, __LINE__, ##args); 
asmlinkage long new_open(char *filename, int flags, int mode) 
{ 
    printk("call open()\n"); 
    return old_open (filename, flags, mode); 
} 
unsigned int clear_and_return_cr0(void) 
{ 
    unsigned long cr0 = 0; 
    unsigned long ret; 
    asm volatile ("movq %%cr0, %%rax" 
       : "=a"(cr0) 
      ); 
    ret = cr0; 
    /* clear the 20 bit of CR0, a.k.a WP bit */ 
    cr0 &= 0xfffffffffffeffff; 
    asm volatile ("movq %%rax, %%cr0" 
       : 
       : "a"(cr0) 
      ); 
    return ret; 
} 
void setback_cr0(unsigned long val) 
{ 
    asm volatile ("movq %%rax, %%cr0" 
       : 
       : "a"(val) 
      ); 
} 
static unsigned long get_syscall_table_long(void) 
{ 
    #define OFFSET_SYSCALL 200 
    unsigned long syscall_long, retval; 
    char sc_asm[OFFSET_SYSCALL]; 
    rdmsrl(MSR_LSTAR, syscall_long); 
    memcpy(sc_asm, (char *)syscall_long, OFFSET_SYSCALL); 
    retval = (unsigned long) memmem(sc_asm, OFFSET_SYSCALL, "/xff/x14/xc5", 3); 
    if (retval != 0) { 
     retval = (unsigned long) (* (unsigned long *)(retval+3)); 
    } else { 
     printk("long mode : memmem found nothing, returning NULL:("); 
     retval = 0; 
    } 
    #undef OFFSET_SYSCALL 
    return retval; 
} 
static void *memmem(const void *haystack, size_t haystack_len, 
      const void *needle, size_t needle_len) 
{ 
    const char *begin; 
    const char *const last_possible = (const char *) haystack + haystack_len - needle_len; 
    if (needle_len == 0){ 
     /* The first occurrence of the empty string is deemed to occur at 
      the beginning of the string. */ 
     return (void *) haystack; 
    } 
    if (__builtin_expect(haystack_len < needle_len, 0)){ 
     return NULL; 
    } 
    for (begin = (const char *) haystack; begin <= last_possible; ++begin) 
    { 
     if (begin[0] == ((const char *) needle)[0] 
      && !memcmp((const void *) &begin[1], 
        (const void *) ((const char *) needle + 1), 
        needle_len - 1)){ 
      return (void *) begin; 
     } 
    } 
    return NULL; 
} 
static int init_sys_call_table(void) 
{ 
    printk("init_sys_call_table\n"); 
    unsigned long orig_cr0 = clear_and_return_cr0(); 
    printk("orig_cr0 %lu\n",orig_cr0); 
    sys_table = (unsigned long *) get_syscall_table_long(); 
    if (sys_table == 0){ 
     dbg("sys_table == 0/n"); 
     return -1; 
    } 
    sys_table = (unsigned long)sys_table | 0xffffffff00000000; 
#define REPLACE(x) old_##x = sys_table[__NR_##x];\ 
    sys_table[__NR_##x] = new_##x 
    REPLACE(open); 
    setback_cr0(orig_cr0); 
    return 0; 
} 
static void clean_sys_call_table(void) 
{ 
    unsigned long orig_cr0 = clear_and_return_cr0(); 
#define RESTORE(x) sys_table[__NR_##x] = old_##x 
    RESTORE(open); 
    setback_cr0(orig_cr0); 
    return ; 
} 
static int __init init_64mod(void) 
{ 
    init_sys_call_table(); 
    return 0; 
} 
static void __exit exit_64mod(void) 
{ 
    clean_sys_call_table(); 
} 
module_init(init_64mod); 
module_exit(exit_64mod); 
MODULE_AUTHOR("[email protected]"); 

risposta

5

Ciò significa che da qualche parte nel codice si dispone di un puntatore non valido che si sta tentando di accedere. Non posso eseguire il debug di codice al volo ma posso darvi alcuni suggerimenti:

  • cercare di evitare di fusione fino a quando è strettamente necessario
  • quando si sta lanciando a un puntatore, doppio controllo che è ciò che si vuole non
  • nel messaggio di errore v'è anche lo stack, dare un'occhiata a esso al fine di identificare dove è l'errore
  • si può semplicemente mettere un po 'printk("%p", pointer) nel codice per controllare il contenuto delle variabili. In alternativa, è possibile utilizzare systemtap (o strumenti simili) a
Problemi correlati