From: Jiri Slaby <jirislaby@gmail.com>
To: News Letter <newletter.yhl@gmail.com>
Cc: linux-kernel@vger.kernel.org
Subject: Re: Question about a strange behavior of copy_to_user() in ioctl call
Date: Tue, 19 Jun 2007 09:54:46 +0200 [thread overview]
Message-ID: <46778BC6.8020001@gmail.com> (raw)
In-Reply-To: <48a616c60706181753m7fefd35as7f6093d2d54ae05@mail.gmail.com>
News Letter napsal(a):
> Hi,
>
> I need some help here to understand copy_to_user(). I encountered a
> strange copy_to_user() behavior when working on CentOS from Redhat
> (kernel version 2.6.9-22.ELsmp, x86_64 CPU).
>
> For a kernel module, I wrote a ioctl call to allow user mode program
> to get some kernel data information. When a user program called the
> ioctl, most of the time the ioctl failed with EFAULT, failed at
> copy_to_user(). It succeeded a few times after a lot of running.
>
> Failed message indicated copy_to_user() returned 3840 (which is
> exactly what is asked to copy, PAGE_SIZE-256). The printed value of
> the user pointer were identical for successful ioctl calls and failed
> ioctl calls. Some relevant details are at the end of this email. I
> tried with calloc(PAGE_SIZE, 1), static buffer and automatic variable
> on stack in user mode program. They gave the same result.
>
> I appreciate any help.
>
> Best,
> Jasper
>
> The ioctl call structure is defined as follows,
>
> struct ioctl_get_info
> {
> ... /* some other information */
> unsigned long user_pointer;
> unsigned user_buffer_len;
> unsigned returned_len;
> ... /* some other information */
> };
>
> Inside kernel module, a page is allocated with :
>
> static unsigned char *test_page;
>
> static init_test(void)
> {
> test_page = __get_free_pages(GFP_KERNEL, 0);
> if (!test_page)
> .... /* some error handling */
> }
>
> static int test_ioctl(struct inode * inode, struct file * filp,
> unsigned int cmd_in, unsigned long arg)
> {
> struct ioctl_get_info igi;
> unsigned size;
> unsigned long remain;
>
> size = IOC_SIZE(cmd_in);
> if (size != sizeof(igi))
> ....
>
> ... /* some sanity checking */
>
> if (!access_ok(VERIFY_READ, (char *)arg, size))
> {
> printk(KERN_INFO "...");
> return -EFAULT;
> }
>
> if (copy_from_user(&igi, (char *)arg, size) != 0)
> {
> printk(... ...)
> return -EFAULT;
> }
>
> if (!access_ok(VERIFY_WRITE, (char *)igi.user_pointer,
> igi.user_buffer_len))
> {
> printk(...);
> return -EFAULT;
> }
>
> size = PAGE_SIZE - 256;
> if (size > igi.user_buffer_len)
> size = igi.user_buffer_len;
> printk("igi.user_pointer %p size %u\n", igi.user_pointer, size);
Weird. Are you sure, that previous access_ok doesn't fail with this 'size', not
the 'igi.user_buffer_len'? Anyway, you can remove these access_ok checks, since
they are provided by copy_from/to_user after debugging.
> if ((remain = copy_to_user((char *)igi.user_pointer, page + 256,
> size)) != 0)
> {
> printk ("Failed to copy from user at %p remain %lu asked %u\n",
> igi.user_pointer, remain, asked);
> /* failed here */
> return -EFAULT;
> }
> igi.returned_len = size;
>
> /* copy other information */
>
> return 0;
> }
regards,
--
http://www.fi.muni.cz/~xslaby/ Jiri Slaby
faculty of informatics, masaryk university, brno, cz
e-mail: jirislaby gmail com, gpg pubkey fingerprint:
B674 9967 0407 CE62 ACC8 22A0 32CC 55C3 39D4 7A7E
next prev parent reply other threads:[~2007-06-19 7:54 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-19 0:53 Question about a strange behavior of copy_to_user() in ioctl call News Letter
2007-06-19 7:54 ` Jiri Slaby [this message]
2007-06-19 14:59 ` News Letter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=46778BC6.8020001@gmail.com \
--to=jirislaby@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=newletter.yhl@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.