How to use copy_from_user correctly?

I am trying to copy a value from user space to kernel space using a function:

static ssize_t device_write(struct file *filp, const char *buff, size_t len, loff_t *off) { unsigned long copy=0; int desp=0; copy = copy_from_user(&desp, &len, 4); printk(KERN_ALERT "copy: %lx\n", copy); printk(KERN_ALERT "desp: %d\n", desp); } 

where "len" is a variable that exists in user space, and I want to copy it to "desp" in kernel space

calling a function that I am making from user space (the record is device_write according to file_operations struct):

  write (fd,buffer,8, &off); 

when I print the value that should be stored in "desp" is always 0 (should be 8). What is the problem in my code? I saw a few examples, and I implemented many options, but no one works.

+4
source share
2 answers

The prototype of the write function in the manual is:

ssize_t write(int fd, const void *buf, size_t count);

Therefore, you need to transfer only 3 values ​​to write , namely: the file descriptor fd , buffer , where your data is located, and count bytes that you want to write.

This applies to user space. Now we turn to the function of writing to kernel space, i.e. Your device_write .

The buf argument for this function is the one that contains the data you want to write from user space, count is the length of the data sent for writing by the kernel. Thus, you should copy the data from the buf pointer, not len .

So the correct way:

 char *desp; //allocate memory for this in kernel using malloc copy_from_user (desp, buff, len); 

It has to be done.

+4
source

len does not exist in user space. It is passed by value, so len is available as a normal variable in kernel space. desp = (int)len is all you need. Please note, however, that size_t does not match int, but on 64-bit platforms, size_t is 8 bytes.

copy_from_user() is for the buffer you are trying to write (called buffer in your user space code and buff in the kernel argument list). A past pointer to a memory address that exists only in user space, therefore copy_from_user() copies this buffer to the kernel space buffer.

+4
source

Source: https://habr.com/ru/post/1489913/


All Articles