我正在尝试使用系统调用将两个数字加在一起,然后通过指针将结果分配给内存位置。我已经设置了系统调用并为此编写了一个测试,但是当我尝试通过解引用传递的指针来分配结果时,系统调用失败。我在系统调用和指针方面缺少什么?
系统调用
#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
答案 0 :(得分:2)
您应该使用copy_to_user
将数据安全地复制到用户空间。
内核空间不应直接取消对用户空间指针的引用-指针可能无效,该位置的内存可能不可用(可能会换出)。