Как мне скопировать целое число из пространства ядра с помощью copy_to_user?

#c #linux #linux-kernel

#c #linux #linux-ядро

Вопрос:

Проблема

Я не могу скопировать данные.


Пользовательское пространство

Вот мое пользовательское пространство:

 #include<stdio.h>
#include<stdlib.h>
#include<linux/kernel.h>
#include<sys/syscall.h>
#include<unistd.h>
#include<pwd.h>
#include<sys/sysinfo.h>

int main (int argc, char *argv[])
{
    void *mytask;
    short allsize;
    struct sysinfo si;
    struct passwd *passwdStruct;

    // to get the userid of my raspberry pi so i can see all of us processes

    const char * usrnm = argv[1];
    passwdStruct = getpwnam(usrnm);
    uid_t usrid = passwdStruct->pw_uid;

    // testing grabbing information 
    int holder = 7;
    void * ptr; // im making this a void pointer b/c copy_to_user takes a void * as parameter
    ptr = amp;holder;

    printf("old stuff: %dn", holder);

    int sys_retval = syscall(398, usrid, allsize, ptr);

    printf("new stuff: n");
    printf("p: %dn", holder);

    return 0;
}
  

Пространство ядра

Вот мое пространство ядра:

 #include<linux/kernel.h>
#include<linux/init.h>
#include<linux/sched.h>
#include<linux/syscalls.h>
//#include<linux/pwd.h> // includes the passwd struct which has id
//#include<sys/types.h> 
#include "mycall.h"
#include <linux/unistd.h>



asmlinkage long sys_sayhello(uid_t myusername, int siz, void __user *ptr)
{
    uid_t myid = myusername;
    const void *kern; // 2nd argument for copy_to_user
    struct task_struct *mytask;

// collect all the necessary info into the kernel array 
    for_each_process(mytask)
    {
        if (myid == mytask->cred->uid.val) // if the process belongs to the pi user
        {
            kern = amp;(mytask->pid); // I looked up kernel documentation and 
            copy_to_user(ptr, kern, sizeof(int)); // looks like pid is an INT type
            return;
        }
    }

    return 0;
}
  

Вывод

Программа выводит:

«старый материал: 7 новых материалов: 7»


Вопрос

Число должно было измениться на первое в pid моем pi процессе в выходных данных. Как мне решить эту проблему?

Комментарии:

1. Возможно, это не имеет прямого отношения к вашей проблеме, но все приведение указателей не имеет никакого эффекта. Ядру все равно, какой тип, по мнению пользовательской программы, имел указатель; его интересуют только биты. И почему бы просто не создать все pid_t вместо того, чтобы гадать о размере int ?

2. Возможно, вам следует вставить некоторый printk, чтобы проверить, будет ли ваш if (myid == ...) когда-либо успешным. Возможно, вам вообще никогда не удастся выполнить copy_to_user . Если вы это сделаете, вы также можете захотеть проверить возвращаемое значение copy_to_user .

3. Действительно, вы пробовали заставить copy_to_user работать в более простом случае? int foo = 12345; if(copy_to_user(ptr, amp;foo, sizeof(int)) != 0) printk("failn");

4. Наконец, проверьте значение sys_retval и, при необходимости, значение errno . Если вы получите ENOSYS , ваш системный вызов фактически не вызывается.