* why "probe_kernel_address()", not "probe_user_address()"?
@ 2006-10-28 15:56 Robert P. J. Day
2006-10-28 16:29 ` Andrew Morton
0 siblings, 1 reply; 8+ messages in thread
From: Robert P. J. Day @ 2006-10-28 15:56 UTC (permalink / raw)
To: Linux Kernel Mailing List
it seems odd that the purpose of the "probe_kernel_address()" macro
is, in fact, to probe a *user* address (from linux/uaccess.h):
#define probe_kernel_address(addr, retval) \
({ \
long ret; \
\
inc_preempt_count(); \
ret = __get_user(retval, addr); \
dec_preempt_count(); \
ret; \
})
given that that routine is referenced only 5 places in the entire
source tree, wouldn't it be more meaningful to use a more appropriate
name?
pedantically yours,
rday
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: why "probe_kernel_address()", not "probe_user_address()"?
2006-10-28 15:56 why "probe_kernel_address()", not "probe_user_address()"? Robert P. J. Day
@ 2006-10-28 16:29 ` Andrew Morton
2006-10-28 16:52 ` Robert P. J. Day
2006-10-28 17:02 ` Robert P. J. Day
0 siblings, 2 replies; 8+ messages in thread
From: Andrew Morton @ 2006-10-28 16:29 UTC (permalink / raw)
To: Robert P. J. Day; +Cc: Linux Kernel Mailing List
On Sat, 28 Oct 2006 11:56:24 -0400 (EDT)
"Robert P. J. Day" <rpjday@mindspring.com> wrote:
>
> it seems odd that the purpose of the "probe_kernel_address()" macro
> is, in fact, to probe a *user* address (from linux/uaccess.h):
>
> #define probe_kernel_address(addr, retval) \
> ({ \
> long ret; \
> \
> inc_preempt_count(); \
> ret = __get_user(retval, addr); \
> dec_preempt_count(); \
> ret; \
> })
>
> given that that routine is referenced only 5 places in the entire
> source tree, wouldn't it be more meaningful to use a more appropriate
> name?
>
You'll notice that all callers are indeed probing kernel addresses. The
function _could_ be used for user addresses and could perhaps be called
probe_address().
One of the reasons this wrapper exists is to communicate that the
__get_user() it is in fact not being used to access user memory.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: why "probe_kernel_address()", not "probe_user_address()"?
2006-10-28 16:29 ` Andrew Morton
@ 2006-10-28 16:52 ` Robert P. J. Day
2006-10-28 17:02 ` Robert P. J. Day
1 sibling, 0 replies; 8+ messages in thread
From: Robert P. J. Day @ 2006-10-28 16:52 UTC (permalink / raw)
To: Andrew Morton; +Cc: Linux Kernel Mailing List
On Sat, 28 Oct 2006, Andrew Morton wrote:
> On Sat, 28 Oct 2006 11:56:24 -0400 (EDT)
> "Robert P. J. Day" <rpjday@mindspring.com> wrote:
>
> >
> > it seems odd that the purpose of the "probe_kernel_address()" macro
> > is, in fact, to probe a *user* address (from linux/uaccess.h):
> >
> > #define probe_kernel_address(addr, retval) \
> > ({ \
> > long ret; \
> > \
> > inc_preempt_count(); \
> > ret = __get_user(retval, addr); \
> > dec_preempt_count(); \
> > ret; \
> > })
> >
> > given that that routine is referenced only 5 places in the
> > entire source tree, wouldn't it be more meaningful to use a more
> > appropriate name?
>
> You'll notice that all callers are indeed probing kernel addresses.
> The function _could_ be used for user addresses and could perhaps be
> called probe_address().
>
> One of the reasons this wrapper exists is to communicate that the
> __get_user() it is in fact not being used to access user memory.
um ... ok. i think. i agree that "probe_address()" would be a more
appropriate name, but i'm still a bit confused as to why
"__get_user()" would be used to access something *not* in user memory,
given this seemingly unambiguous explanation in
include/asm-i386/uaccess.h:
=====
* get_user: - Get a simple variable from user space.
* @x: Variable to store result.
* @ptr: Source address, in user space.
*
* Context: User context only. This function may sleep.
*
* This macro copies a single simple variable from user space to kernel
* space. It supports simple types like char and int, but not larger
* data types like structures or arrays.
...
=====
so having probe_kernel_address() invoke __get_user() does seem to be
just a wee bit confusing for us newbies. in any event, i'll leave the
clarification for someone much higher up the food chain.
rday
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: why "probe_kernel_address()", not "probe_user_address()"?
2006-10-28 16:29 ` Andrew Morton
2006-10-28 16:52 ` Robert P. J. Day
@ 2006-10-28 17:02 ` Robert P. J. Day
2006-10-28 20:30 ` Luca Tettamanti
1 sibling, 1 reply; 8+ messages in thread
From: Robert P. J. Day @ 2006-10-28 17:02 UTC (permalink / raw)
To: Andrew Morton; +Cc: Linux Kernel Mailing List
On Sat, 28 Oct 2006, Andrew Morton wrote:
> On Sat, 28 Oct 2006 11:56:24 -0400 (EDT)
> "Robert P. J. Day" <rpjday@mindspring.com> wrote:
>
> >
> > it seems odd that the purpose of the "probe_kernel_address()" macro
> > is, in fact, to probe a *user* address (from linux/uaccess.h):
> >
> > #define probe_kernel_address(addr, retval) \
> > ({ \
> > long ret; \
> > \
> > inc_preempt_count(); \
> > ret = __get_user(retval, addr); \
> > dec_preempt_count(); \
> > ret; \
> > })
> >
> > given that that routine is referenced only 5 places in the entire
> > source tree, wouldn't it be more meaningful to use a more appropriate
> > name?
> >
>
> You'll notice that all callers are indeed probing kernel addresses.
> The function _could_ be used for user addresses and could perhaps be
> called probe_address().
>
> One of the reasons this wrapper exists is to communicate that the
> __get_user() it is in fact not being used to access user memory.
one quick addition to this. in arch/i386/kernel/traps.c, we have the
code snippet:
if (eip < PAGE_OFFSET)
return;
if (probe_kernel_address((unsigned short __user *)eip, ud2))
return;
if (ud2 != 0x0b0f)
return;
printk(KERN_EMERG "------------[ cut here ]------------\n");
#ifdef CONFIG_DEBUG_BUGVERBOSE
do {
unsigned short line;
char *file;
char c;
if (probe_kernel_address((unsigned short __user *)(eip + 2),
line))
... etc etc ...
if those pointers qualified by "__user" *aren't* actually addresses
into user space, that would seem to violate what i read in the book
"linux device drivers (3rd ed)", p. 50:
"This [__user] annotation is a form of documentation, noting that a
pointer is a user-space address that cannot be directly dereferenced.
For normal compilation, __user has no effect, but it can be used by
external checking software to find misuse of user-space addresses."
under the circumstances, wouldn't this show up as one of those
misuses?
rday
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: why "probe_kernel_address()", not "probe_user_address()"?
2006-10-28 17:02 ` Robert P. J. Day
@ 2006-10-28 20:30 ` Luca Tettamanti
2006-10-28 21:01 ` Robert P. J. Day
2006-10-29 13:02 ` Denis Vlasenko
0 siblings, 2 replies; 8+ messages in thread
From: Luca Tettamanti @ 2006-10-28 20:30 UTC (permalink / raw)
To: Robert P. J. Day; +Cc: linux-kernel
Robert P. J. Day <rpjday@mindspring.com> ha scritto:
> On Sat, 28 Oct 2006, Andrew Morton wrote:
>
>> On Sat, 28 Oct 2006 11:56:24 -0400 (EDT)
>> "Robert P. J. Day" <rpjday@mindspring.com> wrote:
>>
>> >
>> > it seems odd that the purpose of the "probe_kernel_address()" macro
>> > is, in fact, to probe a *user* address (from linux/uaccess.h):
>> >
>> > #define probe_kernel_address(addr, retval) \
>> > ({ \
>> > long ret; \
>> > \
>> > inc_preempt_count(); \
>> > ret = __get_user(retval, addr); \
>> > dec_preempt_count(); \
>> > ret; \
>> > })
>> >
>> > given that that routine is referenced only 5 places in the entire
>> > source tree, wouldn't it be more meaningful to use a more appropriate
>> > name?
>> >
>>
>> You'll notice that all callers are indeed probing kernel addresses.
>> The function _could_ be used for user addresses and could perhaps be
>> called probe_address().
>>
>> One of the reasons this wrapper exists is to communicate that the
>> __get_user() it is in fact not being used to access user memory.
>
> one quick addition to this. in arch/i386/kernel/traps.c, we have the
> code snippet:
>
> if (eip < PAGE_OFFSET)
> return;
> if (probe_kernel_address((unsigned short __user *)eip, ud2))
> return;
> if (ud2 != 0x0b0f)
> return;
>
> printk(KERN_EMERG "------------[ cut here ]------------\n");
>
> #ifdef CONFIG_DEBUG_BUGVERBOSE
> do {
> unsigned short line;
> char *file;
> char c;
>
> if (probe_kernel_address((unsigned short __user *)(eip + 2),
> line))
> ... etc etc ...
>
I agree that it may be confusing. The whole point in using __get_user()
is that it ensures that the source address is valid.
When handle_BUG() is called the kernel is no more in a "sane" state,
blindly using the content of the registers may lead to a page fault in
kernel mode. So the code extract filename and line of the BUG checking
that the line number is indeed readable, the address of the string (file
name) is readable and it points to a readable memory location.
probe_kernel_address wrapper is used to "hide" the fact that we are
re-using the infrastructure provided by a function with a confusing name
;) The cast to __user is needed to keep sparse quiet.
> if those pointers qualified by "__user" *aren't* actually addresses
> into user space, that would seem to violate what i read in the book
> "linux device drivers (3rd ed)", p. 50:
>
> "This [__user] annotation is a form of documentation, noting that a
> pointer is a user-space address that cannot be directly dereferenced.
> For normal compilation, __user has no effect, but it can be used by
> external checking software to find misuse of user-space addresses."
>
> under the circumstances, wouldn't this show up as one of those
> misuses?
No, __user annotation ensure that sparse will notice things like:
int random_pointer_from_userspace __user *data;
...
my_data = *data; /* <-- sparse will complain */
In this scenario 'data' is a pointer provided by userspace application
and *cannot* be trusted; it shall be used only with functions that do
check the address before using it, like __get_user(). (get_user() also
checks that the address is a *userspace* address, it can't be used to
read kernel memory).
Luca
--
Se alla sera, dopo una strepitosa vittoria, guardandoti allo
specchio dovessi notare un secondo paio di palle, che il tuo
cuore non si riempia d'orgoglio, perche` vuol dire che ti
stanno inculando -- Saggio Cinese
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: why "probe_kernel_address()", not "probe_user_address()"?
2006-10-28 20:30 ` Luca Tettamanti
@ 2006-10-28 21:01 ` Robert P. J. Day
2006-10-29 15:49 ` Luca Tettamanti
2006-10-29 13:02 ` Denis Vlasenko
1 sibling, 1 reply; 8+ messages in thread
From: Robert P. J. Day @ 2006-10-28 21:01 UTC (permalink / raw)
To: Luca Tettamanti; +Cc: linux-kernel
On Sat, 28 Oct 2006, Luca Tettamanti wrote:
> I agree that it may be confusing. The whole point in using
> __get_user() is that it ensures that the source address is valid.
>
> When handle_BUG() is called the kernel is no more in a "sane" state,
> blindly using the content of the registers may lead to a page fault
> in kernel mode. So the code extract filename and line of the BUG
> checking that the line number is indeed readable, the address of the
> string (file name) is readable and it points to a readable memory
> location.
>
> probe_kernel_address wrapper is used to "hide" the fact that we are
> re-using the infrastructure provided by a function with a confusing
> name ;) The cast to __user is needed to keep sparse quiet.
... more response snipped ...
ok, i'm going to defer to people who are clearly much smarter about
this than me, and i'll go back and read that entire response more
carefully until i understand it. thanks for explaining it.
rday
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: why "probe_kernel_address()", not "probe_user_address()"?
2006-10-28 20:30 ` Luca Tettamanti
2006-10-28 21:01 ` Robert P. J. Day
@ 2006-10-29 13:02 ` Denis Vlasenko
1 sibling, 0 replies; 8+ messages in thread
From: Denis Vlasenko @ 2006-10-29 13:02 UTC (permalink / raw)
To: Luca Tettamanti; +Cc: Robert P. J. Day, linux-kernel
On Saturday 28 October 2006 22:30, Luca Tettamanti wrote:
> probe_kernel_address wrapper is used to "hide" the fact that we are
> re-using the infrastructure provided by a function with a confusing name
> ;) The cast to __user is needed to keep sparse quiet.
Shouldn't the above text be placed in a comment above probe_kernel_address()
definition? ;)
--
vda
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: why "probe_kernel_address()", not "probe_user_address()"?
2006-10-28 21:01 ` Robert P. J. Day
@ 2006-10-29 15:49 ` Luca Tettamanti
0 siblings, 0 replies; 8+ messages in thread
From: Luca Tettamanti @ 2006-10-29 15:49 UTC (permalink / raw)
To: Robert P. J. Day; +Cc: linux-kernel
Il Sat, Oct 28, 2006 at 05:01:31PM -0400, Robert P. J. Day ha scritto:
> ok, i'm going to defer to people who are clearly much smarter about
> this than me, and i'll go back and read that entire response more
> carefully until i understand it.
Well, if you tell me what is not clear I can try to re-explain it.
> thanks for explaining it.
No problem, the best way to learn about the kernel is reading the source
and asking questions ;)
Luca
--
Mi piace avere amici rispettabili;
Mi piace essere il peggiore della compagnia.
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2006-10-29 15:50 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-28 15:56 why "probe_kernel_address()", not "probe_user_address()"? Robert P. J. Day
2006-10-28 16:29 ` Andrew Morton
2006-10-28 16:52 ` Robert P. J. Day
2006-10-28 17:02 ` Robert P. J. Day
2006-10-28 20:30 ` Luca Tettamanti
2006-10-28 21:01 ` Robert P. J. Day
2006-10-29 15:49 ` Luca Tettamanti
2006-10-29 13:02 ` Denis Vlasenko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox