Skip to content
Advertisement

BUG: unable to handle kernel paging request when accessing a custom struct in syscall

Using linux with kernel 4.4.21, I was required to implement a system call which has a custom struct’s pointer among its parameters. These are the files to to edit:

// in linux-4.4.21/arch/x86/entry/syscalls/syscall_64.tbl :
546 x32 procmem         sys_procmem

// in linux-4.4.21/include/linux/syscalls.h :
struct proc_segs;
asmlinkage longsys_procmem (int pid, struct proc_segs *info);

I put sys_procmem.c (implementation) in linux-4.4.21/kernel/sys_procmem.c (sys_procmem.o added in that dir’s Makefile):

#include <linux/linkage.h>
#include <linux/sched.h>
#include <linux/kernel.h>

struct proc_segs
{
  unsigned long stID;
};

asmlinkage long sys_procmem (int pid, struct proc_segs *info)
{
  printk("sys_procmem called n"); // this is fine in dmesg
  info->stID = 1234567; // KILLED
  return 0;
}

Test:

#include <sys/syscall.h>
#include <unistd.h>
#include <stdio.h>

struct proc_segs
{
  unsigned long stID;
};

int main() {
  unsigned long info[10];
  long sysval = syscall(546, 1, info);
  printf("My stID : %lun", info[0]);
} // I have no idea why this works (or not on me), but it was included in the excercise's manual
//or:
int main() {
  struct proc_segs info;
  syscall(546, getpid(), &info);
  printf("My stID : %lun", info.stID);
}

Both were killed miserably.

dmesg:

[ 3298.944925] sys_procmem called
[ 3298.944997] BUG: unable to handle kernel paging request at 00007ffe570aa8e0
[ 3298.945005] IP: [<ffffffff8109d540>] sys_procmem+0x140/0x280
[ 3298.945017] PGD 7a919067 PUD 790a6067 PMD 7a82f067 PTE 800000004c530867
[ 3298.945027] Oops: 0003 [#2] SMP 
[ 3298.945047] Modules linked in: bnep rfcomm bluetooth btrfs xor qxl raid6_pq snd_hda_codec_generic ttm snd_hda_intel snd_hda_codec kvm_intel drm_kms_helper snd_hda_core kvm drm snd_hwdep snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device irqbypass snd_timer crct10dif_pclmul snd crc32_pclmul aesni_intel aes_x86_64 fb_sys_fops lrw syscopyarea glue_helper soundcore sysfillrect ablk_helper sysimgblt joydev lpc_ich cryptd input_leds serio_raw mac_hid parport_pc ppdev lp parport hid_generic usbhid hid e1000e psmouse ahci libahci virtio_blk
[ 3298.945122] CPU: 5 PID: 2752 Comm: test-procmem Tainted: G      D         4.4.21.1810887 #13
[ 3298.945126] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS ?-20191223_100556-anatol 04/01/2014
[ 3298.945130] task: ffff88002c1e96c0 ti: ffff880079f68000 task.ti: ffff880079f68000
[ 3298.945134] RIP: 0010:[<ffffffff8109d540>]  [<ffffffff8109d540>] sys_procmem+0x140/0x280
[ 3298.945142] RSP: 0018:ffff880079f6bf38  EFLAGS: 00010282
[ 3298.945145] RAX: 0000000000000024 RBX: ffff88013bb98000 RCX: 0000000000000006
[ 3298.945148] RDX: 0000000000000000 RSI: 0000000000000246 RDI: ffff88013fd4db30
[ 3298.945151] RBP: ffff880079f6bf48 R08: 000000000000000a R09: 0000000000000000
[ 3298.945154] R10: 0000000000000000 R11: 0000000000000304 R12: 00007ffe570aa8e0
[ 3298.945157] R13: 00007ffe570aaa10 R14: 0000000000000000 R15: 0000000000000000
[ 3298.945161] FS:  00007fe88da41740(0000) GS:ffff88013fd40000(0000) knlGS:0000000000000000
[ 3298.945165] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 3298.945168] CR2: 00007ffe570aa8e0 CR3: 000000007acb0000 CR4: 00000000003406e0
[ 3298.945177] Stack:
[ 3298.945180]  0000000000000000 0000000000400490 00007ffe570aa930 ffffffff817e7676
[ 3298.945187]  0000000000000000 0000000000000000 00007ffe570aaa10 0000000000000000
[ 3298.945196]  0000000000000000 00007fe88d82d6c8 0000000000000202 00007fe88d82ee80
[ 3298.945205] Call Trace:
[ 3298.945229]  [<ffffffff817e7676>] entry_SYSCALL_64_fastpath+0x16/0x75
[ 3298.945234] Code: 00 48 8b b0 08 01 00 00 31 c0 e8 69 b6 0d 00 48 8b 83 48 07 00 00 48 c7 c7 e4 51 aa 81 48 8b b0 18 01 00 00 31 c0 e8 4d b6 0d 00 <49> c7 04 24 c7 a1 1b 00 48 c7 c7 01 52 aa 81 31 c0 e8 37 b6 0d 
[ 3298.945315] RIP  [<ffffffff8109d540>] sys_procmem+0x140/0x280
[ 3298.945322]  RSP <ffff880079f6bf38>
[ 3298.945325] CR2: 00007ffe570aa8e0
[ 3298.945330] ---[ end trace 0b79468970c7e49f ]---

This was done inside a 64-bit Ubuntu 14.04 virtual machine. My friends had no problems when they use VirtualBox or VMWare Player, mine was KVM/QEMU (although the instructor advised us to use the former two explicitly, kernel compilation was indeed faster with KVM). Does a different hypervisor have anything to do with this?

Advertisement

Answer

Thanks to the comments. I have added copy_from_user and copy_to_user.

Now it works.

#include <linux/uaccess.h>
// struct definition
asmlinkage long sys_procmem (int pid, struct proc_segs *info)
{

  printk("sys_procmem called n");
  struct proc_segs temp_info;
  copy_from_user(&temp_info, info, sizeof(struct proc_segs));
  info->stID = 1234567;
  copy_to_user(info, &temp_info, sizeof(struct proc_segs));
  return 0;
}
User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement