All of lore.kernel.org
 help / color / mirror / Atom feed
* Understanding of write file operation in char driver
@ 2015-01-02  2:20 me storage
  2015-01-02 16:02 ` Valdis.Kletnieks at vt.edu
  0 siblings, 1 reply; 6+ messages in thread
From: me storage @ 2015-01-02  2:20 UTC (permalink / raw)
  To: kernelnewbies

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/char_simple.c
>
>
>
>
>
>
>
>
> > Thanks & Regards
> > Prasad
> >
> >
> > _______________________________________________
> > Kernelnewbies mailing list
> > Kernelnewbies at kernelnewbies.org
> > http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150102/e20fc7a3/attachment.html 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Understanding of write file operation in char driver
  2015-01-02  2:20 Understanding of write file operation in char driver me storage
@ 2015-01-02 16:02 ` Valdis.Kletnieks at vt.edu
  2015-01-03 15:53   ` me storage
  0 siblings, 1 reply; 6+ messages in thread
From: Valdis.Kletnieks at vt.edu @ 2015-01-02 16:02 UTC (permalink / raw)
  To: 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....
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 848 bytes
Desc: not available
Url : http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150102/804deb31/attachment.bin 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Understanding of write file operation in char driver
  2015-01-02 16:02 ` Valdis.Kletnieks at vt.edu
@ 2015-01-03 15:53   ` me storage
  2015-01-03 18:19     ` Pranay Srivastava
  0 siblings, 1 reply; 6+ messages in thread
From: me storage @ 2015-01-03 15:53 UTC (permalink / raw)
  To: kernelnewbies

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....
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150103/9b505b78/attachment.html 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Understanding of write file operation in char driver
  2015-01-03 15:53   ` me storage
@ 2015-01-03 18:19     ` Pranay Srivastava
  0 siblings, 0 replies; 6+ messages in thread
From: Pranay Srivastava @ 2015-01-03 18:19 UTC (permalink / raw)
  To: kernelnewbies

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 at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>



-- 
        ---P.K.S

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Understanding of write file operation in char driver
  2015-01-01  8:24 me storage
@ 2015-01-01 15:50 ` Victor Rodriguez
  0 siblings, 0 replies; 6+ messages in thread
From: Victor Rodriguez @ 2015-01-01 15:50 UTC (permalink / raw)
  To: kernelnewbies

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/char_simple.c








> Thanks & Regards
> Prasad
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies at kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Understanding of write file operation in char driver
@ 2015-01-01  8:24 me storage
  2015-01-01 15:50 ` Victor Rodriguez
  0 siblings, 1 reply; 6+ messages in thread
From: me storage @ 2015-01-01  8:24 UTC (permalink / raw)
  To: kernelnewbies

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?

Thanks & Regards
Prasad
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20150101/835ee5a1/attachment.html 

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-01-03 18:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-02  2:20 Understanding of write file operation in char driver me storage
2015-01-02 16:02 ` Valdis.Kletnieks at vt.edu
2015-01-03 15:53   ` me storage
2015-01-03 18:19     ` Pranay Srivastava
  -- strict thread matches above, loose matches on Subject: below --
2015-01-01  8:24 me storage
2015-01-01 15:50 ` Victor Rodriguez

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.