0
**

[  105.823895] BUG: unable to handle kernel paging request at ffffffffc06ed026
[  105.823899] PGD 13c80e067 P4D 13c80e067 PUD 13c810067 PMD 12f1d0067 PTE 0
[  105.823901] Oops: 0010 [#1] SMP NOPTI
[  105.823903] CPU: 2 PID: 2935 Comm: bash Tainted: G           OE     4.19.67-2018202030 #7
[  105.823904] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  105.823907] RIP: 0010:0xffffffffc06ed026
[  105.823910] Code: Bad RIP value.
[  105.823910] RSP: 0018:ffffb129843cbf28 EFLAGS: 00010286
[  105.823911] RAX: 0000000000000001 RBX: 0000000000000000 RCX: ffff8e4e001cb900
[  105.823912] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff8e4e2918f2d8
[  105.823913] RBP: ffffb129843cbf28 R08: 0000000000000000 R09: 0000000000000000
[  105.823913] R10: ffffb129843cbe98 R11: 0000000000000000 R12: ffffb129843cbf58
[  105.823914] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  105.823915] FS:  00007fd974ed2700(0000) GS:ffff8e4e3de80000(0000) knlGS:0000000000000000
[  105.823915] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  105.823916] CR2: ffffffffc06ecffc CR3: 00000000b5d0e000 CR4: 0000000000340ee0
[  105.823932] Call Trace:
[  105.823938]  do_syscall_64+0x5a/0x110
[  105.823941]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  105.823942] RIP: 0033:0x7fd9745c6360
[  105.823943] Code: 0b 31 c0 48 83 c4 08 e9 ae fe ff ff 48 8d 3d 27 b4 09 00 e8 b2 1e 02 00 66 90 83 3d e9 23 2d 00 00 75 10 b8 00 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 5e de 01 00 48 89 04 24
[  105.823944] RSP: 002b:00007ffeb6b5eb98 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
[  105.823945] RAX: ffffffffffffffda RBX: 00007fd9748938e0 RCX: 00007fd9745c6360
[  105.823946] RDX: 0000000000000001 RSI: 00007ffeb6b5eba7 RDI: 0000000000000000
[  105.823946] RBP: 00000000004d7d4a R08: 00007fd974895770 R09: 00007fd974ed2700
[  105.823947] R10: 662f37362e39312e R11: 0000000000000246 R12: 000000000045f7d0
[  105.823947] R13: 0000000000000001 R14: 0000000000000000 R15: 00007ffeb6b5ed60
[  105.823948] Modules linked in: rfcomm bnep snd_ens1371 snd_ac97_codec gameport ac97_bus btusb btrtl snd_pcm crct10dif_pclmul snd_seq_midi snd_seq_midi_event crc32_pclmul ghash_clmulni_intel snd_rawmidi vmw_balloon pcbc snd_seq snd_seq_device snd_timer btbcm btintel snd bluetooth aesni_intel aes_x86_64 crypto_simd cryptd glue_helper input_leds joydev serio_raw soundcore ecdh_generic i2c_piix4 mac_hid vmw_vsock_vmci_transport vsock vmw_vmci parport_pc ppdev lp parport autofs4 hid_generic usbhid hid vmwgfx ttm drm_kms_helper mptspi mptscsih syscopyarea sysfillrect mptbase sysimgblt fb_sys_fops drm psmouse e1000 scsi_transport_spi ahci libahci pata_acpi [last unloaded: ftracehooking]
[  105.823975] CR2: ffffffffc06ed026
[  105.823976] ---[ end trace 2530693e2a17bef8 ]---
[  105.823977] RIP: 0010:0xffffffffc06ed026
[  105.823978] Code: Bad RIP value.
[  105.823979] RSP: 0018:ffffb129843cbf28 EFLAGS: 00010286
[  105.823980] RAX: 0000000000000001 RBX: 0000000000000000 RCX: ffff8e4e001cb900
[  105.823980] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff8e4e2918f2d8
[  105.823981] RBP: ffffb129843cbf28 R08: 0000000000000000 R09: 0000000000000000
[  105.823981] R10: ffffb129843cbe98 R11: 0000000000000000 R12: ffffb129843cbf58
[  105.823982] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  105.823983] FS:  00007fd974ed2700(0000) GS:ffff8e4e3de80000(0000) knlGS:0000000000000000
[  105.823983] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  105.823984] CR2: ffffffffc06ecffc CR3: 00000000b5d0e000 CR4: 0000000000340ee0
[  105.829428] BUG: unable to handle kernel paging request at ffffffffc06ed026
[  105.829433] PGD 13c80e067 P4D 13c80e067 PUD 13c810067 PMD 12f1d0067 PTE 0
[  105.829439] Oops: 0010 [#2] SMP NOPTI
[  105.829442] CPU: 1 PID: 1024 Comm: in:imklog Tainted: G      D    OE     4.19.67-2018202030 #7
[  105.829444] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020
[  105.829450] RIP: 0010:0xffffffffc06ed026
[  105.829455] Code: Bad RIP value.
[  105.829456] RSP: 0018:ffffb12981b6bf28 EFLAGS: 00010286
[  105.829459] RAX: 0000000000000ea7 RBX: 0000000000000000 RCX: 0000000000000000
[  105.829460] RDX: ffff8e4e0003ae00 RSI: 0000000000000000 RDI: ffff8e4d979eb200
[  105.829461] RBP: ffffb12981b6bf28 R08: 0000000000000000 R09: 0000000000000000
[  105.829463] R10: ffffb12981b6be98 R11: ffff8e4e3d806e80 R12: ffffb12981b6bf58
[  105.829464] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  105.829466] FS:  00007f3d4182d700(0000) GS:ffff8e4e3de40000(0000) knlGS:0000000000000000
[  105.829468] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  105.829469] CR2: ffffffffc06ecffc CR3: 0000000134a30000 CR4: 0000000000340ee0
[  105.829496] Call Trace:
[  105.829505]  do_syscall_64+0x5a/0x110
[  105.829510]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  105.829512] RIP: 0033:0x7f3d43c7c51d
[  105.829515] Code: be 20 00 00 75 10 b8 00 00 00 00 0f 05 48 3d 01 f0 ff ff 73 31 c3 48 83 ec 08 e8 4e fc ff ff 48 89 04 24 b8 00 00 00 00 0f 05 <48> 8b 3c 24 48 89 c2 e8 97 fc ff ff 48 89 d0 48 83 c4 08 48 3d 01
[  105.829516] RSP: 002b:00007f3d4180c580 EFLAGS: 00000293 ORIG_RAX: 0000000000000000
[  105.829518] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f3d43c7c51d
[  105.829520] RDX: 0000000000001fa0 RSI: 00007f3d4180cda0 RDI: 0000000000000004
[  105.829521] RBP: 00000000011c8320 R08: 0000000000000000 R09: 0000000000000000
[  105.829522] R10: 00007f3d4180c3d0 R11: 0000000000000293 R12: 00007f3d4180cda0
[  105.829524] R13: 0000000000001fa0 R14: 0000000000001f9f R15: 00007f3d4180ce98
[  105.829526] Modules linked in: rfcomm bnep snd_ens1371 snd_ac97_codec gameport ac97_bus btusb btrtl snd_pcm crct10dif_pclmul snd_seq_midi snd_seq_midi_event crc32_pclmul ghash_clmulni_intel snd_rawmidi vmw_balloon pcbc snd_seq snd_seq_device snd_timer btbcm btintel snd bluetooth aesni_intel aes_x86_64 crypto_simd cryptd glue_helper input_leds joydev serio_raw soundcore ecdh_generic i2c_piix4 mac_hid vmw_vsock_vmci_transport vsock vmw_vmci parport_pc ppdev lp parport autofs4 hid_generic usbhid hid vmwgfx ttm drm_kms_helper mptspi mptscsih syscopyarea sysfillrect mptbase sysimgblt fb_sys_fops drm psmouse e1000 scsi_transport_spi ahci libahci pata_acpi [last unloaded: ftracehooking]
[  105.829632] CR2: ffffffffc06ed026
[  105.829635] ---[ end trace 2530693e2a17bef9 ]---
[  105.829638] RIP: 0010:0xffffffffc06ed026
[  105.829641] Code: Bad RIP value.
[  105.829643] RSP: 0018:ffffb129843cbf28 EFLAGS: 00010286
[  105.829644] RAX: 0000000000000001 RBX: 0000000000000000 RCX: ffff8e4e001cb900
[  105.829646] RDX: 0000000000000000 RSI: 0000000000000000 RDI: ffff8e4e2918f2d8
[  105.829647] RBP: ffffb129843cbf28 R08: 0000000000000000 R09: 0000000000000000
[  105.829648] R10: ffffb129843cbe98 R11: 0000000000000000 R12: ffffb129843cbf58
[  105.829649] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
[  105.829651] FS:  00007f3d4182d700(0000) GS:ffff8e4e3de40000(0000) knlGS:0000000000000000
[  105.829653] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  105.829654] CR2: ffffffffc06ecffc CR3: 0000000134a30000 CR4: 0000000000340ee0
os2018202030@ubuntu:~$** 

I learning operating systems. I made a system call hooking and I found that it has a problem with removing it.

Although the system call hooking I made works fine. But when I remove the module from the kernel, it gives this kind of error message. I assume this kind of error is related to the page size of "syscall_table", but I can't find any relation between "syscall_table" and the address that the error message gave me. (I printed syscall_table address, gave me an address starting with 0000XXXXXX.)

those are the header files that I include.

#include <linux/module.h>
#include <linux/highmem.h>
#include <linux/kallsyms.h>
#include <linux/syscalls.h>
#include <asm/syscall_wrapper.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/namei.h>
#include <linux/sched.h>

those are codes that I've written.

    #include "./ftracehooking.h"


#define __NR_ftrace 336                     //trace system call identifier

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiyong Park");
MODULE_DESCRIPTION("ftrace hook");
MODULE_VERSION("0.1");

/* 
trace variables
*/
int read_count = 0;
int read_bytes = 0;

int write_count = 0;
int write_bytes = 0;

int open_count = 0;
char open_file[NAME_MAX] = {0 };

int close_count = 0;

int lseek_count = 0;

/*
make trace variables accessable from dynamically inserted modules
*/
EXPORT_SYMBOL(read_count);
EXPORT_SYMBOL(read_bytes);

EXPORT_SYMBOL(write_count);
EXPORT_SYMBOL(write_bytes);

EXPORT_SYMBOL(open_count);
EXPORT_SYMBOL(open_file);

EXPORT_SYMBOL(close_count);

EXPORT_SYMBOL(lseek_count);

void **syscall_table;                   //pointer to syscall table

static asmlinkage int (* orig_ftrace)(const struct pt_regs *reg);           //a pointer to original syscall 
static asmlinkage int hook_ftrace(const struct pt_regs *reg)                //a ftrace hooking syscall 
{

    pid_t pid = reg->di;                                                    //get first argument of the pt_regs structure
    
    if(pid != 0)                                                            //if current process is parent process whose pid is not 0
    {   
        /*
        initialize variables
        */
        read_count = 0;
        read_bytes = 0;
        
        write_count = 0;
        write_bytes = 0;

        open_count = 0;
        open_file[0] = '\0';

        close_count = 0;
        
        lseek_count = 0;

        printk(KERN_INFO "OS Assignment2 ftrace [%d] Start\n", pid);        //print kernel message
    }
    else
    {
        /*
        if it is child process whose pid is 0, print kernel message below
        we can get current file name from task_struct *current
        */
        printk(KERN_INFO "[2018202030] %s file[%s] start [x] read - %d / written - %d\n", current->comm, open_file, read_bytes, write_bytes);
        printk(KERN_INFO "open[%d] close[%d] read[%d] write[%d] lseek[%d]\n", open_count, close_count, read_count, write_count, lseek_count);
        printk(KERN_INFO "OS Assignment2 ftrace [%d] End\n", pid);
    }

    
    return orig_ftrace(reg);            //call original ftrace syscall and return its return value
}

/*
get read and write permission at address 
*/

void make_rw(void *addr)
{
    unsigned int level;
    pte_t *pte = lookup_address((u64)addr, &level);     //get page table entry of address
    if(pte->pte &~ _PAGE_RW)                            //if there is no write permission on the address
        pte->pte |= _PAGE_RW;                           //turn on read write permission
}



/*
retrieve read only permission at address
*/

void make_ro(void *addr)
{
    unsigned int level;
    pte_t *pte = lookup_address((u64)addr, &level);     //get page table entry of address
    
    pte->pte = pte->pte &~ _PAGE_RW;                    //eliminate write permission
}


static int __init hooking_init(void)
{
    syscall_table = (void **)kallsyms_lookup_name("sys_call_table");        //get syscall table entry
    
    make_rw(syscall_table);                                                 //get page write permission
    orig_ftrace = syscall_table[__NR_ftrace];                               //store original ftrace syscall

    
    syscall_table[__NR_ftrace] = hook_ftrace;                               //hook a user defined syscall

    make_ro(syscall_table);                                                 //eliminate page write permission
    

    return 0;
}


static void __exit hooking_exit(void)
{   
    make_rw(syscall_table);                                                 //get page write permission
    syscall_table[__NR_ftrace] = orig_ftrace;                               //restore pre-defined  syscall

    make_ro(syscall_table);                                                 //eliminate page write permission
}

module_init(hooking_init);                                                  //insert module
module_exit(hooking_exit);                                                  //exit module

#include "./ftracehooking.h"


#define __NR_ftrace 336
 
#define __NR_read   0
#define __NR_write  1
#define __NR_open   2
#define __NR_close  3
#define __NR_lseek  8


MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiyong Park");
MODULE_DESCRIPTION("io trace hook");
MODULE_VERSION("0.1");

void **syscall_table;               //pointer to syscall table

/* 
external trace variables
*/
extern int read_count;
extern int read_bytes;

extern int write_count;
extern int write_bytes;

extern int open_count;
extern char open_file[NAME_MAX];

extern int close_count;

extern int lseek_count;

/*
pointers to original syscall
*/
static asmlinkage long (*orig_read)(const struct pt_regs *);
static asmlinkage long (*orig_write)(const struct pt_regs *);
static asmlinkage long (*orig_open)(const struct pt_regs *);
static asmlinkage long (*orig_close)(const struct pt_regs *);
static asmlinkage long (*orig_lseek)(const struct pt_regs *);

static asmlinkage long ftrace_read(const struct pt_regs *reg)       //read syscall hook
{
    read_bytes += reg->dx;                              //get third argument of the pt_regs structure
    ++read_count;                                       //increase read count
    
    return orig_read(reg);                              //call original read syscall and return its return value
}

static asmlinkage long ftrace_write(const struct pt_regs *reg)      //write syscall hook
{
    write_bytes += reg->dx;                             //get third argument of the pt_regs structure
    ++write_count;                                      //increase write count
    
    return orig_write(reg);                             //call original write syscall and return its return value
}

static asmlinkage long ftrace_open(const struct pt_regs *reg)       //open syscall hook
{
    char __user *pathname = (char *)reg->di;            //get third argument from pt_regs 
    strncpy_from_user(open_file, pathname, NAME_MAX);   //string copy null byte aware
    ++open_count;                                       //increase open count
    
    return orig_open(reg);                              //call original open syscall and return its return value
}

static asmlinkage long ftrace_close(const struct pt_regs *reg)      //close syscall hook
{
    ++close_count;                                      //increase close count
    
    return orig_close(reg);                             //call original close syscall and return its return value
}

static asmlinkage long ftrace_lseek(const struct pt_regs *reg)      //lseek syscall hook
{
    ++lseek_count;                                      //increase lseek count
    
    return orig_lseek(reg);                             //call original lseek syscall and return its return value
}


/*
get read and write permission at address 
*/
/*
void make_rw(void *addr)
{
    unsigned int level;
    pte_t *pte = lookup_address((u64)addr, &level);     //get page table entry of address
    if(pte->pte &~ _PAGE_RW)                            //if there is no write permission on the address
        pte->pte |= _PAGE_RW;                           //turn on read write permission
}
*/

/*
retrieve read only permission at address
*/
/*
void make_ro(void *addr)
{
    unsigned int level;
    pte_t *pte = lookup_address((u64)addr, &level);     //get page table entry of address
    
    pte->pte = pte->pte &~ _PAGE_RW;                    //eliminate write permission
}
*/


static int __init hooking_init(void)
{
    syscall_table = (void **)kallsyms_lookup_name("sys_call_table");        //get syscall table entry
    
    //make_rw(syscall_table);
    write_cr0(read_cr0() & (~0x10000));                                                 //get page write permission

    /*
    store original syscalls
    */
    orig_read = syscall_table[__NR_read];
    orig_write = syscall_table[__NR_write];
    orig_open = syscall_table[__NR_open];
    orig_close = syscall_table[__NR_close];
    orig_lseek = syscall_table[__NR_lseek];
        
    /*
    hook a user defined syscall
    */
    syscall_table[__NR_read] = ftrace_read;
    syscall_table[__NR_write] = ftrace_write;
    syscall_table[__NR_open] = ftrace_open;
    syscall_table[__NR_close] = ftrace_close;
    syscall_table[__NR_lseek] = ftrace_lseek;

    write_cr0(read_cr0() | 0x10000);
    
    return 0;
}

static void __exit hooking_exit(void)
{
    /*
    restore pre-defined  syscall
    */

    write_cr0(read_cr0() & (~0x10000)); 
    syscall_table[__NR_read] = orig_read;
    syscall_table[__NR_write] = orig_write;
    syscall_table[__NR_open] = orig_open;
    syscall_table[__NR_close] = orig_close;
    syscall_table[__NR_lseek] = orig_lseek;

    write_cr0(read_cr0() | 0x10000);
    //make_ro(syscall_table);                                                   //eliminate page write permission
}

module_init(hooking_init);                                                  //insert module
module_exit(hooking_exit);                                                  //exit module

can you guys give me an idea of how to solve this problem?

Sanchez
  • 57
  • 4

0 Answers0