簡體   English   中英

Linux內核syscall返回未給定指針

[英]Linux kernel syscall return not given pointer

我正在嘗試實施一個新的syscall作為實驗,但是我總是遇到段錯誤。 我認為問題是我試圖返回一個指向不在用戶空間中的char數組的指針。 我試圖通過使用GFP_USER作為kmalloc的標志來在用戶空間中分配內存,但是問題仍然相同。

這就是我調用syscall的方式,目前無法更改它(通常將分配內存以供返回,並將其作為參數提供):

#include <errno.h>
#include <linux/unistd.h>
#include <linux/mysyscall.h>

main() {
  printf("Returned: %s\n", mycall("user string arg"));

}

syscall函數的定義如下所示:

#include <linux/mysyscall.h>
#include <linux/kernel.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <asm/uaccess.h>

asmlinkage char* sys_mycall (char * str_in) {
    int size = 0;

    printk(KERN_INFO "Starting mycall.\n");
    size = strnlen_user(str_in, 255);
    printk(KERN_INFO "size = %d\n", size);
    char str[size];
    char *ret;
    ret = kmalloc(size, GFP_ATOMIC | GFP_USER); 

    if(str != NULL){
        copy_from_user(str, str_in, size);
        printk(KERN_INFO "Copied string.\n");
    }else{
        printk(KERN_ERR "str is NULL!!!\n");
        return -EFAULT;
    }

    // Doing operations on str

    int acc = access_ok(VERIFY_WRITE, ret, size);
    if(acc){
        printk(KERN_ERR "Not accessible!\n");
        return -EFAULT; 
    }

    int len = copy_to_user(ret, str, size);
    if(len){
        printk(KERN_ERR "Could not copy! len = %d\n", len);
        return -EFAULT;
    }

    return ret;
} 

我已經對其進行了大量測試,並且可以確定syscall的調用正確,但是copy_to_user存在問題。 copy_to_user始終返回一個正值(等於大小,因此根本不會復制)。
順便說一下,ret的地址就像f74ce400和str_in 080484ac。

有人知道出什么事了嗎?

副本的目標應該是用戶空間指針,而指針ret在內核空間中。 您應該從用戶那里提供目標指針作為參數。 參見例如:

您應該在調用strlen()之前執行copy_from_user。 通常,系統調用會獲得一個額外的參數,並帶有傳遞的參數長度。

對於前; mysyscall(STR,strlen的)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM