2014-11-14 7 views
8

मैंने कुछ लिनक्स कर्नेल कोड लिखा है, जो रनटाइम त्रुटि का कारण बनता है, और linux unable to handle kernel paging request at ffffffff00000010 रिपोर्ट करता है।"linux fffffff00000010 पर कर्नेल पेजिंग अनुरोध को संभालने में असमर्थ" की त्रुटि क्या है?

यह लिनक्स कर्नेल प्रोग्रामिंग में open सिस्टम कॉल को हुक करने के लिए सिर्फ एक कोड है।

कोड नीचे सूचीबद्ध है:

#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]"); 

उत्तर

5

इसका मतलब है कि अपने कोड में कहीं न कहीं आप गलत सूचक है कि आप पहुँचने का प्रयास कर रहे हैं। मैं तेज़ी से अपने कोड डीबग नहीं कर सकते हैं लेकिन मैं आपको कुछ सुझाव दे सकते हैं: कास्टिंग से बचने के लिए

  • कोशिश जब तक अत्यंत आवश्यक होता
  • है जब आप एक सूचक कास्ट कर रहे हैं, दोहरी जांच यह क्या आप चाहते हैं कि त्रुटि संदेश में
  • है वहाँ भी ढेर, ताकि पहचान करने के लिए जहां त्रुटि
  • है तो आप बस अपने चर की सामग्री की जांच करने के लिए अपने कोड में कुछ printk("%p", pointer) रख सकते हैं में यह पर एक नज़र डालें। वैकल्पिक रूप से, आप systemtap (या समान उपकरण) का उपयोग
पर कर सकते हैं
संबंधित मुद्दे