Re: Using acces_ok() in device driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 2008-08-19 at 00:54 +0200, Bartek Dolewski wrote:
> Hi all
> Again I have problems with some kernel programming stuff. I decided to
> make my first device driver more robust. So I wanted to add
> access_ok() both in function read() and write() from fops. But when I
> type: echo "Message" >> /dev/mydevice   I get this error:
> bash: echo: write error: Bad address
> 
> Here my source code. First, implementation of read() function:
> 
> static ssize_t    FirstModule_Write(struct file *flip, const char
> *buffer, size_t length, loff_t *off)
> {
>     int i;
> 
>     if(!access_ok(VERIFY_READ, buffer, length));

the actual problem is the ";" at the end of above line so in case of
true of false the if statement does nothing. in the next line below it
simply return -EFAULT in whatever the case.


>     return -EFAULT;
> 
>     for(i=0; i < length && i < BUF_LEN; i++)
>         get_user(msg2[i],buffer+i);
>     msg2_Ptr = msg2;
>     printk(KERN_INFO "Your message from Userland is: %s",msg2);
> 
> I think that I have to verify reading mode because I`ll get some data
> from userspace buffer. Second argument is of course address of this
> buffer and last one ... that`s right, I don`t know how to interpret
> this argument. It is some length of memory block. There is the snippet
> from #include <asm/uaccess.h>:
> * access_ok: - Checks if a user space pointer is valid
>  * @type: Type of access: %VERIFY_READ or %VERIFY_WRITE.  Note that
>  *             %VERIFY_WRITE is a superset of %VERIFY_READ - if it is safe
>  *             to write to a block, it is always safe to read from it.
>  * @addr: User space pointer to start of block to check
>  * @size: Size of block to check
> Size of what block ? Size of address of this buffer or WHOLE buffer ?
> My invocation of access_ok() is based on this code
> (drivers/char/mem.c) :
> 
>  static ssize_t read_port(struct file * file, char __user * buf,
>                           size_t count, loff_t *ppos)
>  {
>          unsigned long i = *ppos;
>          char __user *tmp = buf;
> 
>          if (!access_ok(VERIFY_WRITE, buf, count))
>                  return -EFAULT;
>          while (count-- > 0 && i < 65536) {
>                  if (__put_user(inb(i),tmp) < 0)
>                          return -EFAULT;
>                  i++;
>                 tmp++;
>          }
>          *ppos = i;
>         return tmp-buf;
>  }
> 
> I thought my code is good but not. Of course not. If someone have some
> ideas just go ahead :) And thanks for any explanation :)
> 
> -----BEGIN GEEK CODE BLOCK-----
> GCS d- s:- a--- C+++ P L+++>+++++ E---- W+ N+ o? K- w--- O- M- V? PS++
> PE++ Y PGP++ t--- 5? X R tv-- b+ DI+ D- G++ e- h! !r(--) !z+
> ------END GEEK CODE BLOCK------
> 
> --
> To unsubscribe from this list: send an email with
> "unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
> Please read the FAQ at http://kernelnewbies.org/FAQ
> 


 regarding access_ok I think the below should explain you .. its taken
from linux device driver 3 book ch: 6

To start, address verification (without transferring data) is
implemented by the function access_ok, which isdeclared in
<asm/uaccess.h>: int access_ok(int type, const void *addr, unsigned long
size);

The first argument should be either VERIFY_READ or VERIFY_WRITE,
depending on whether the action to be performed is reading the
user-space memory area or writing it. The addr argument holds a
user-space address, and size is a byte count. If ioctl, for instance,
needs to read an integer value from user space, size is sizeof(int). If
you need to both read and write at the given address, use VERIFY_WRITE,
since it is a superset of VERIFY_READ. Unlike most kernel functions,
access_ok returns a boolean value: 1 for success (access is OK) and 0
for failure (access is not OK). If it returns false, the driver should
usu- ally return -EFAULT to the caller.

There are a couple of interesting things to note about access_ok. First,
it does not do the complete job of verifying memory access; it only
checks to see that the memory reference is in a region of memory that
the process might reasonably have access to. In particular, access_ok
ensures that the address does not point to kernel-space memory. Second,
most driver code need not actually call access_ok.


-- 
H. Mohamed Thalib


--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ


[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux