4

I write a kernel module which replaces syscall and have a problem. Module can't be loaded because is some problem in memory. I tried fix it for 3 hours, but it still not work. This code is working, when I choose memory closer sys_call_table (eg. linux_banner address from /proc/kallsyms), but it isn't always works.

Problem is usually, when function which search syscall table points to address which end is 18 (eg ffffffff91000018, ffffffff81000018).

Why it does not work?

Code:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/syscalls.h>
#include <linux/list.h>
#include <linux/unistd.h>
#include <linux/kobject.h>
#include <linux/init.h>

 /* start of 64-bit kernel space is 0xffffffff80000000 */
#define END_MEM   0xffffffffffffffff /* end of 64-bit kernel */
#define START_MEM 0xffffffff81000000

unsigned long long **syscall_tab;
asmlinkage long (*orig_mkdir)(const char __user *pathname, umode_t mode);

asmlinkage long my_mkdir(const char __user *pathname, umode_t mode)
{
  long ret;
  ret = orig_mkdir(pathname, mode);
  printk("Creating dir: %s", pathname);
  return ret;
}

static void hide(void)
{
  list_del(&THIS_MODULE->list);
  kobject_del(&THIS_MODULE->mkobj.kobj);
}
static unsigned long long **find(void) {
    unsigned long long **sctable;
    unsigned long long i = START_MEM;

    while (i < END_MEM) {
        sctable = (unsigned long long **) i;

        if ( sctable[__NR_close] == (unsigned long long *) sys_close) {
            printk("syscall_tab %lx", syscall_tab);
            return &sctable[0];
        }
        i += sizeof(void *);
    }

    return NULL;
}

static int __init init(void)
{
  write_cr0(read_cr0() & (~0x10000));
  if(!(syscall_tab = find())) {
    return 0;
  }
  orig_mkdir = (void *) syscall_tab[__NR_mkdir];

  printk("write_cr0");
  syscall_tab[__NR_mkdir] = (unsigned long long*) my_mkdir;
  printk("po podmiance");
  write_cr0(read_cr0() | (~0x10000));
  return 0;
}

static void __exit exitt(void)
{
  write_cr0(read_cr0() & (~0x10000));
  syscall_tab[__NR_mkdir] = (unsigned long long*) orig_mkdir;
  write_cr0(read_cr0() | (~0x10000));
}
module_init(init);
module_exit(exitt);
MODULE_LICENSE("GPL");

Error:

[  299.273838] BUG: unable to handle kernel paging request at ffffffff91000018
[  299.273856] IP: init+0x23/0x1000 [hijack1]
[  299.273860] PGD b6a0c067 
[  299.273861] P4D b6a0c067 
[  299.273863] PUD b6a0d063 
[  299.273866] PMD 0 

[  299.273872] Oops: 0000 [#1] PREEMPT SMP
[  299.273877] Modules linked in: hijack1(O+) fuse rfcomm bnep nls_iso8859_1 nls_cp437 vfat fat intel_rapl x86_pkg_temp_thermal intel_powerclamp coretemp kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul crc32c_intel ghash_clmulni_intel pcbc aesni_intel joydev ppdev hp_wmi mousedev iTCO_wdt aes_x86_64 sparse_keymap iTCO_vendor_support mei_wdt crypto_simd psmouse glue_helper pcspkr evdev input_leds cryptd mac_hid intel_cstate intel_rapl_perf uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_v4l2 videobuf2_core btusb btrtl btbcm btintel bluetooth cdc_ether ecdh_generic usbnet videodev uas media mii hid_generic nouveau mxm_wmi ttm arc4 drm_kms_helper iwldvm drm syscopyarea sysfillrect mac80211 sysimgblt iwlwifi fb_sys_fops parport_pc parport snd_hda_codec_hdmi i2c_algo_bit snd_hda_codec_idt cfg80211
[  299.273953]  rfkill snd_hda_codec_generic hp_accel thermal lis3lv02d wmi input_polldev tpm_infineon video ac battery button snd_hda_intel snd_hda_codec snd_hda_core snd_hwdep snd_pcm shpchp snd_timer e1000e snd ptp soundcore tpm_tis mei_me mei pps_core lpc_ich tpm_tis_core tpm sch_fq_codel vboxnetflt(O) vboxnetadp(O) pci_stub vboxpci(O) vboxdrv(O) sg ip_tables x_tables ext4 crc16 jbd2 fscrypto mbcache sr_mod sd_mod cdrom usb_storage usbhid hid serio_raw atkbd libps2 ahci libahci libata scsi_mod xhci_pci xhci_hcd ehci_pci sdhci_pci ehci_hcd sdhci firewire_ohci led_class firewire_core mmc_core crc_itu_t usbcore usb_common i8042 serio
[  299.274005] CPU: 2 PID: 3384 Comm: insmod Tainted: G           O    4.12.4-1-ARCH #1
[  299.274009] Hardware name: Hewlett-Packard HP EliteBook 8560w/1631, BIOS 68SVD Ver. F.60 03/12/2015
[  299.274014] task: ffff90127cc0c740 task.stack: ffffb72907298000
[  299.274019] RIP: 0010:init+0x23/0x1000 [hijack1]
[  299.274023] RSP: 0018:ffffb7290729bc88 EFLAGS: 00010206
[  299.274027] RAX: 0000000080040033 RBX: ffffffff91000000 RCX: 0000000000000000
[  299.274031] RDX: 00000000004bec82 RSI: 00000000004bec82 RDI: 0000000080040033
[  299.274036] RBP: ffffb7290729bc90 R08: ffff901339003980 R09: ffffffffa018970a
[  299.274040] R10: ffffe481c211ebc0 R11: 0000000000000000 R12: ffffffffc0030000
[  299.274044] R13: ffff9012377965e0 R14: ffffffffc0a81050 R15: ffff90132e0eca80
[  299.274049] FS:  00007f9a842a4b80(0000) GS:ffff90133dc80000(0000) knlGS:0000000000000000
[  299.274053] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080040033
[  299.274057] CR2: ffffffff91000018 CR3: 000000007cdb9000 CR4: 00000000000406e0
[  299.274061] Call Trace:
[  299.274068]  do_one_initcall+0x50/0x190
[  299.274073]  ? do_init_module+0x27/0x1e6
[  299.274077]  do_init_module+0x5f/0x1e6
[  299.274082]  load_module+0x2610/0x2ab0
[  299.274087]  ? vfs_read+0x115/0x130
[  299.274091]  SYSC_finit_module+0xf6/0x110
[  299.274095]  ? SYSC_finit_module+0xf6/0x110
[  299.274100]  SyS_finit_module+0xe/0x10
[  299.274105]  entry_SYSCALL_64_fastpath+0x1a/0xa5
[  299.274109] RIP: 0033:0x7f9a839b3bb9
[  299.274111] RSP: 002b:00007ffd2386ee28 EFLAGS: 00000206 ORIG_RAX: 0000000000000139
[  299.274120] RAX: ffffffffffffffda RBX: 00007f9a83c74aa0 RCX: 00007f9a839b3bb9
[  299.274124] RDX: 0000000000000000 RSI: 000000000041aada RDI: 0000000000000003
[  299.274128] RBP: 00007f9a83c74af8 R08: 0000000000000000 R09: 00007f9a83c76e40
[  299.274132] R10: 0000000000000003 R11: 0000000000000206 R12: 0000000000001020
[  299.274136] R13: 0000000000001018 R14: 00007f9a83c74af8 R15: 0000000000000001
[  299.274141] Code: <48> 81 7b 18 40 a8 21 a0 75 2d 48 8b 35 14 13 a5 00 48 c7 c7 35 00 
[  299.276347] RIP: init+0x23/0x1000 [hijack1] RSP: ffffb7290729bc88
[  299.277333] CR2: ffffffff91000018
[  299.283408] ---[ end trace 63ac9e1e3a0e12c3 ]---
Mario Boss
  • 1,784
  • 3
  • 20
  • 43

1 Answers1

0

Syscall hijacking x64- unable to handle kernel paging request at ffffffff91000018...

I write kernel module which replace syscall and have a problem. Module can't be loaded because is some problem in memory. I tried fix it for 3 hours, but it still not work...

The problem is, hijacking syscalls is not technically feasible. You can't do it with Linux. Linux does not have a layered design that supports this sort of thing (as opposed to Windows or other operating systems).

About the best you will be able to do is interpositioning, which redirects calls made through the PLT into your shared object. I believe this is the way Valgrind works when it replaces malloc and free.

Also note that some system calls are not routed through the PLT. See the discussion of Double-underscore names for public API functions on the glibc wiki.

Also see Query regarding kernel modules intercepting system call on the Kernel Newbies mailing list and Multiple kernel modules intercepting same system call and crash during unload on Stack Overflow. The first one is the question where the kernel developers tell OP is not possible. I'm just reiterating what the kernel dev's have already stated.

jww
  • 97,681
  • 90
  • 411
  • 885
  • Thank you, but in 32-bit system syscall hijacking was possible, well why its not technically feasible in this case? – Wiktoria Lewicka Oct 05 '17 at 16:45
  • @Wiktoria - this is not my area of expertise so take it with a grain of salt. However, I tend to believe the kernel devs when they say it is not possible. Maybe you should ask for clarification on the kernel newbies mailing list. The kernel devs are much more approachable on the kernel newbies mailing list. You swim with the sharks on other kernel mailing lists :) – jww Oct 05 '17 at 16:55