如何通过系统调用为点分配值?

时间:2018-09-12 20:06:51

标签: c linux-kernel operating-system

我正在尝试使用系统调用将两个数字加在一起,然后通过指针将结果分配给内存位置。我已经设置了系统调用并为此编写了一个测试,但是当我尝试通过解引用传递的指针来分配结果时,系统调用失败。我在系统调用和指针方面缺少什么?

系统调用

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

asmlinkage long sys_simple_add(int val1, int val2, int *retAddress) {
    int retValue = val1 + val2;
    *retAddress = retValue;     //This is where the system call fails according to the /var/log/syslog
    printk(KERN_ALERT "Value 1: %d \t Value 2: %d \t Result: %d", val1, val2, retValue);
    return 0;
}

带有系统调用的测试代码。

#define _GNU_SOURCE
#include <stdio.h>
#include <sys/unistd.h>

int main (void) {
    int x = 5;
    int y = 10;
    int retValue;
    int *retAddress = &retValue;

    long returnStatus = syscall(334, x, y, retAddress);
    if (!returnStatus) {
        printf("Value 1: %d \t Value 2: %d \t Result: %d \n", x, y, retValue);
    }
    return 0;
}

通话后的日志。

Sep 12 14:19:09 cu-cs-vm kernel: [   45.314581] BUG: unable to handle kernel paging request at 00007ffffd47e680
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314602] IP: sys_simple_add+0x9/0x30
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314607] PGD 8000000428efb067 P4D 8000000428efb067 PUD 428efa067 PMD 3d4794067 PTE 800000038ef40867
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314621] Oops: 0003 [#1] SMP PTI
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314626] Modules linked in: kvm_intel kvm irqbypass crct10dif_pclmul crc32_pclmul ghash_clmulni_intel pcbc aesni_intel aes_x86_64 crypto_simd glue_helper cryptd vmw_balloon joydev input_leds serio_raw intel_rapl_perf shpchp i2c_piix4 mac_hid vmw_vsock_vmci_transport vsock vmw_vmci binfmt_misc parport_pc ppdev lp parport autofs4 vmwgfx ttm hid_generic usbhid hid drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops drm psmouse mptspi mptscsih mptbase ahci e1000 scsi_transport_spi libahci pata_acpi
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314706] CPU: 5 PID: 1920 Comm: test Not tainted 4.15.18PA1 #6
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314710] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 05/19/2017
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314716] RIP: 0010:sys_simple_add+0x9/0x30
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314721] RSP: 0018:ffffc22783327f28 EFLAGS: 00010206
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314727] RAX: ffffffffa0a6ead0 RBX: ffffc22783327f58 RCX: 000000000000000f
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314731] RDX: 00007ffffd47e680 RSI: 000000000000000a RDI: 0000000000000005
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314735] RBP: ffffc22783327f48 R08: 0000000000000026 R09: 0000000000000001
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314739] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314742] R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314749] FS:  00007f869172e700(0000) GS:ffff9fa1ad740000(0000) knlGS:0000000000000000
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314753] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314758] CR2: 00007ffffd47e680 CR3: 0000000429388001 CR4: 00000000003606e0
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314870] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314874] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314878] Call Trace:
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314892]  ? do_syscall_64+0x73/0x130
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314903]  entry_SYSCALL_64_after_hwframe+0x3d/0xa2
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314908] RIP: 0033:0x7f86912624d9
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314913] RSP: 002b:00007ffffd47e658 EFLAGS: 00000202 ORIG_RAX: 000000000000014e
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314918] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f86912624d9
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314922] RDX: 00007ffffd47e680 RSI: 000000000000000a RDI: 0000000000000005
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314926] RBP: 00007ffffd47e6a0 R08: 0000000000000026 R09: 0000000000000001
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314930] R10: 0000000000000000 R11: 0000000000000202 R12: 00000000004004e0
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314934] R13: 00007ffffd47e780 R14: 0000000000000000 R15: 0000000000000000
Sep 12 14:19:09 cu-cs-vm kernel: [   45.314939] Code: 90 90 0f 1f 44 00 00 55 48 c7 c7 4e 29 ac a1 48 89 e5 e8 5b f8 07 00 31 c0 5d c3 90 90 90 90 90 90 90 0f 1f 44 00 00 8d 0c 37 55 <89> 0a 48 89 e5 89 f2 89 fe 48 c7 c7 60 29 ac a1 e8 32 f8 07 00 
Sep 12 14:19:09 cu-cs-vm kernel: [   45.315025] RIP: sys_simple_add+0x9/0x30 RSP: ffffc22783327f28
Sep 12 14:19:09 cu-cs-vm kernel: [   45.315028] CR2: 00007ffffd47e680
Sep 12 14:19:09 cu-cs-vm kernel: [   45.315035] ---[ end trace 22b1e68d2410810c ]---

以及用于simple_add.o的目标文件的转储

simple_add.o:     file format elf64-x86-64


Disassembly of section .text:

0000000000000000 <sys_simple_add>:
#include <linux/kernel.h>
#include <linux/linkage.h>

asmlinkage long sys_simple_add(int val1, int val2, int *retAddress) {
   0:   e8 00 00 00 00          callq  5 <sys_simple_add+0x5>
    int retValue = val1 + val2;
   5:   8d 0c 37                lea    (%rdi,%rsi,1),%ecx
#include <linux/kernel.h>
#include <linux/linkage.h>

asmlinkage long sys_simple_add(int val1, int val2, int *retAddress) {
   8:   55                      push   %rbp
    int retValue = val1 + val2;
    *retAddress = retValue;
   9:   89 0a                   mov    %ecx,(%rdx)
#include <linux/kernel.h>
#include <linux/linkage.h>

asmlinkage long sys_simple_add(int val1, int val2, int *retAddress) {
   b:   48 89 e5                mov    %rsp,%rbp
    int retValue = val1 + val2;
    *retAddress = retValue;
    printk(KERN_ALERT "Value 1: %d \t Value 2: %d \t Result: %d", val1, val2, retValue);
   e:   89 f2                   mov    %esi,%edx
  10:   89 fe                   mov    %edi,%esi
  12:   48 c7 c7 00 00 00 00    mov    $0x0,%rdi
  19:   e8 00 00 00 00          callq  1e <sys_simple_add+0x1e>
return 0;
  1e:   31 c0                   xor    %eax,%eax
  20:   5d                      pop    %rbp
  21:   c3                      retq   

1 个答案:

答案 0 :(得分:2)

您应该使用copy_to_user将数据安全地复制到用户空间。

内核空间不应直接取消对用户空间指针的引用-指针可能无效,该位置的内存可能不可用(可能会换出)。