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; }