Re: Understanding of write file operation in char driver
Hi All, Thanks Victor Can any one please tell me difference between kernal space & user space in code perspective i.e in write function const char *buffer should point to address of *hello* in RAM so how it is changing when i am accessing through some kernel function because it is also accessing the same RAM address? Thanks & Regards Prasad On 1 January 2015 at 21:20, Victor Rodriguez <vm.rod25@gmail.com> wrote:
On Thu, Jan 1, 2015 at 2:24 AM, me storage <me.storage126@gmail.com> wrote:
I am learning char drivers.But i didn't understand write operation of char device driver properly. the below is my write operation
static ssize_t dev_write(struct file *fil,const char __user *buff,size_t len,loff_t *off) { pr_info("user input string %s\n",buff); pr_info("user input string len %d\n",len); return len; }
my doubt is if i write into my device like echo "hello" > /dev/myDev
it is giving different behaviour like below is the dmesg [20596.975355] user input string hello [20596.975355] 77b9e4 [20596.975355] insmod insmod [20596.975355] n/zeitgeist-daemon [20596.975355] atives [20596.975355] [20596.975355] vars "${upargs[@]}" [20596.975355] cur cword words=(); [20596.975355] local upargs=() upvars=() vcur vcword vprev vwords; [20596.975355] while getopts "c:i:n:p:w:" flag "$@"; do [20596.975355] case $flag in [20596.975355] c) [20596.975355] vcur=$OPTARG [20596.975355] ;; [20596.975355] i) [20596.975355] vcword=$OPTARG [20596.975355] ;; [20596.975355] n) [20596.975355] exclude=$OPTARG [20596.975355] ;; [20596.975355] p) [20596.975355] vprev=$OPTARG [20596.975355] ;; [20596.975355] w) [20596.975355] vwords=$OPTARG [20596.975355] ;; [20596.975358] user input string len 6 [20596.975361] Device closed
so i didn't understand what is happening inside .Can any one please explain what is happening?
HI Prasad
The problem is ont he part where you try to print the buffer on dmesg. I tested this code ( the base full code is on my github repo as char_simple.c *):
106 static ssize_t device_write(struct file *filp, 107 const char *buf, 108 size_t len, 109 loff_t * off) 110 { 111 112 procfs_buffer_size = len; 113 114 115 if ( copy_from_user(buffer_data, buf, procfs_buffer_size) ) { 116 return -EFAULT; 117 } 118 *off += len; 119 120 pr_info("user input string %s\n",buffer_data); 121 //pr_info("user input string len %lu\n",procfs_buffer_size); 122 123 return procfs_buffer_size; 124 }
And the dmesg output is :
[ 2735.251589] Hello from the Kernel !!! (how cool is that) [ 2735.251600] Major Number = 244 [ 2735.251604] Name = mychardriver [ 2735.251607] Generate the device file with mknod /dev/mychardriver c 244 0 [ 2766.806455] user input string hello there
Remember to first do the copy from user space and then print that variable instead of just the buff variable. Print the len is fine (https://gist.github.com/17twenty/6313566 ) however when you try to print the string from the user space , there is where we have the problems (I did the experiment )
Here are some useful links:
http://www.ibm.com/developerworks/library/l-kernel-memory-access/ https://www.kernel.org/doc/htmldocs/kernel-api/ch04s02.html
Hope it helps
Regards
Victor Rodriguez
*char_simple.c :
https://github.com/VictorRodriguez/linux_device_drivers_tutorial/blob/master...
Thanks & Regards Prasad
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
On Fri, 02 Jan 2015 07:50:55 +0530, me storage said:
Can any one please tell me difference between kernal space & user space in code perspective
Two biggies: 1) Kernel space pages are usually nailed down and not paging in and out, this is *not* true for userspace pages (so special tap-dancing in copy_(to/from)_user() is needed to make sure no page faults happen). 2) Data inside the kernel can usually be trusted from a security standpoint. Data in userspace *MUST NOT* be trusted. Also, beware of TOCTOU (time of check / time of use) bugs - that's why we should copy the user-supplied data to an internal buffer *first*, and then validity-check the buffer - if we check the value in userspace and then later copy it, there's a race condition where the userspace value can be changed after the check but before the copy. Also, keep in mind that a userspace pointer needs to be translated before using it to dereference data from kernel space....
Hi, Thanks Valdis for your nice explanation. After practising i got another doubt if read from my driver as below cat /dev/myDev for this how many times read function will call because some times it is executing only once but some times it is executing infinite times. Like for write also echo "hello" > /dev/myDev for that particular call it is executing 1 or 2 times. So can one please clarify my doubts Thanks & Regards Prasad On 2 January 2015 at 21:32, <Valdis.Kletnieks@vt.edu> wrote:
On Fri, 02 Jan 2015 07:50:55 +0530, me storage said:
Can any one please tell me difference between kernal space & user space in code perspective
Two biggies:
1) Kernel space pages are usually nailed down and not paging in and out, this is *not* true for userspace pages (so special tap-dancing in copy_(to/from)_user() is needed to make sure no page faults happen).
2) Data inside the kernel can usually be trusted from a security standpoint. Data in userspace *MUST NOT* be trusted. Also, beware of TOCTOU (time of check / time of use) bugs - that's why we should copy the user-supplied data to an internal buffer *first*, and then validity-check the buffer - if we check the value in userspace and then later copy it, there's a race condition where the userspace value can be changed after the check but before the copy.
Also, keep in mind that a userspace pointer needs to be translated before using it to dereference data from kernel space....
Hi Prasad, On Sat, Jan 3, 2015 at 9:23 PM, me storage <me.storage126@gmail.com> wrote:
Hi, Thanks Valdis for your nice explanation. After practising i got another doubt if read from my driver as below
cat /dev/myDev
for this how many times read function will call because some times it is executing only once but some times it is executing infinite times. Like for write also echo "hello" > /dev/myDev for that particular call it is executing 1 or 2 times. So can one please clarify my doubts
Make sure you return the correct amount to be read based on the amount asked and the amount of data available from current value of fpos. If there's nothing to read then return 0 based on the current value of fpos. Doing strace would help. You would see that cat stops if the amount of data read is lesser than it asks for which is usually a page. Try using generic read/write routines and instead override the readpage(s)/writepage(s) of aops. You won't need to handle those checks then.
Thanks & Regards Prasad
On 2 January 2015 at 21:32, <Valdis.Kletnieks@vt.edu> wrote:
On Fri, 02 Jan 2015 07:50:55 +0530, me storage said:
Can any one please tell me difference between kernal space & user space in code perspective
Two biggies:
1) Kernel space pages are usually nailed down and not paging in and out, this is *not* true for userspace pages (so special tap-dancing in copy_(to/from)_user() is needed to make sure no page faults happen).
2) Data inside the kernel can usually be trusted from a security standpoint. Data in userspace *MUST NOT* be trusted. Also, beware of TOCTOU (time of check / time of use) bugs - that's why we should copy the user-supplied data to an internal buffer *first*, and then validity-check the buffer - if we check the value in userspace and then later copy it, there's a race condition where the userspace value can be changed after the check but before the copy.
Also, keep in mind that a userspace pointer needs to be translated before using it to dereference data from kernel space....
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
-- ---P.K.S
participants (3)
-
me storage -
Pranay Srivastava -
Valdis.Kletnieks@vt.edu