From: Jaco Kroon <jaco@kroon.co.za>
To: kernel-janitors@vger.kernel.org
Subject: Re: [KJ] proper casting (if any) in copy_to_user() calls?
Date: Mon, 08 Jan 2007 16:15:15 +0000 [thread overview]
Message-ID: <45A26E13.30409@kroon.co.za> (raw)
In-Reply-To: <Pine.LNX.4.64.0701050850140.1045@localhost.localdomain>
[-- Attachment #1.1: Type: text/plain, Size: 4070 bytes --]
Thomas Petazzoni wrote:
> Hi,
>
> Le Sat, 6 Jan 2007 13:32:30 +0200 (SAST),
> "Jaco Kroon" <jaco@kroon.co.za> a écrit :
>
>
>>Whilst we're on the topic, I know it's "bad" to dereference a
>>user-space pointer, but from what I understand the actual pointer
>>value remains the same, so as long as you are in the context of the
>>userspace program that gave you the pointer, the VMT should correctly
>>interpret it right?
>>
>>So what exactly is so bad about dereferencing userspace pointers?
>
> The page may not be mapped, for example if it has been swapped out. The
> copy_to_user() and copy_from_user() macros are specifically designed to
> handle that: they add an entry in an exception table, which is read by
> the page fault handler. An entry in that exception table says to the
> page fault handler "yeah, ok, a page fault occured from the kernel, but
> it's perfectly controlled, it's inside a copy_from_user() or
> copy_to_user() macro".
Ok. Note that although I did an "Operating Systems" course during my
university years I still don't think I'm up to scratch, which is why I
lurk (mostly) on this mailing list, no real need for the kernel-level
knowledge, but some really interresting stuff none the less. Anyhow, my
understanding of page-faults is that the MMU (yea, I live in an x86/64
world so other architectures may have different names for things)
generates an interrupt (Of the non-maskable kind?) to the CPU which then
gets handled by the kernel by suspending that process after scheduling
the required page to be swapped back in, or in the worst case, killing
the process with SIGSEGV if no such page exists for the process. So I
guess this flags two guestions:
1. What prevents the kernel page fault handler from doing the same?
2. Would that even be sane?
For question one, let's assume a 3GB/1GB memory split for user/kernel
memory, what then prevents the page-fault-handler from checking in which
"half" the pointer is, if it's in the top 1GB (kernel land) then kernel
panic as is currently the case as that memory can obviously not be paged
in (kernel memory as far as I understand it is stuck in real memory).
If however, we are in the bottom 3GB, grab the page table for the
current task, and check whether it would be possible to swap in the
appropriate pages (I'm guessing this is what copy_{to,from}_user
essentially does).
However, based on what could all go wrong I'm guessing there are just
way too many cases to cover. For example, what if we keep a reference
of that pointer which is then later used in "pure" kernel context
(interrupt of sorts?) or even in another task context. This would be bad.
Or what happens if we have a spinlock of sorts, or a mutex or any other
type of lock which now gets hold because the execution is first sent on
a side-trip? For that matter, what currently happens with
copy_{to,from}_user should this happen?
What happens if that memory cannot be made available? SIGSEGV and
termination of the entire task? What about locks or does
copy_{to,from}_user return error codes indicating failure which can then
be percolated up the call chain until the system call eventually returns
an error, and of course at which point any pending (SIGSEGV) signals
gets delivered?
> Without an entry in the exception table (which would be the case if you
> simply dereference an userspace pointer in the kernel code), then you
> would get a panic from the page fault handler if the page has been
> unmapped for some reason (not yet mapped, swapped out, or whatever).
Sounds like a sane way to prevent all the brainwork that would be
required to allow userspace-pointer dereferences.
> You can have a look at how the copy_to_user()/copy_from_user() macros
> are implemented: they do some ELF-section trickery to add an entry in
> the exception table.
Guess I should do that.
> (Don't hesitate to correct me if I'm wrong).
Not from my side, what you said makes perfect sense. Thanks for the
explanation.
Jaco
[-- Attachment #1.2: S/MIME Cryptographic Signature --]
[-- Type: application/x-pkcs7-signature, Size: 3233 bytes --]
[-- Attachment #2: Type: text/plain, Size: 168 bytes --]
_______________________________________________
Kernel-janitors mailing list
Kernel-janitors@lists.osdl.org
https://lists.osdl.org/mailman/listinfo/kernel-janitors
prev parent reply other threads:[~2007-01-08 16:15 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-01-05 13:54 [KJ] proper casting (if any) in copy_to_user() calls? Robert P. J. Day
2007-01-06 6:31 ` Ahmed S. Darwish
2007-01-06 7:47 ` Jaco Kroon
2007-01-06 8:23 ` Robert P. J. Day
2007-01-06 9:07 ` Robert P. J. Day
2007-01-06 11:32 ` Jaco Kroon
2007-01-08 13:11 ` Thomas Petazzoni
2007-01-08 16:15 ` Jaco Kroon [this message]
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=45A26E13.30409@kroon.co.za \
--to=jaco@kroon.co.za \
--cc=kernel-janitors@vger.kernel.org \
/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.