In the 2.4.18-2.4.19 timeframe:
http://linux.bkbits.net:8080/linux-2.4/[email protected]
brcl (Ben LaHaise, I think) pushed in a change to mm/slab.c which
(amongst other things) adds the following code:
...
name = cachep->name;
===> {
===> char tmp;
===> if (__get_user(tmp, name))
===> name = "broken";
===> }
seq_printf(m, "%-17s %6lu %6lu %6u %4lu %4lu %4u",
name, active_objs, num_objs, cachep->objsize,
active_slabs, num_slabs, (1<<cachep->gfporder));
...
to s_show() (the stuff that gets called when somebody cat's /proc/slabinfo)
Trouble is that on my ARM platform, the __get_user() call always fails
and all the slabinfo entries are labelled "broken".
For my purposes, ifdef'ing the offending block out will likely be
sufficient (and safe?) but I'd like to know:
1. Is the ARM __get_user() broken?
2. Could I be doing something else broken that is confusing __get_user()?
3. What was/is the intent of the test? Or stated differently, why on earth
would cachep->name be a user address?
-g
On Wed, 27 Nov 2002 15:15:17 -0500
Georg Nikodym <[email protected]> wrote:
> 1. Is the ARM __get_user() broken?
> 2. Could I be doing something else broken that is confusing __get_user()?
> 3. What was/is the intent of the test? Or stated differently, why on earth
> would cachep->name be a user address?
In answer to my own question, reading the 2.5 source was illuminating.
The intent of the test is obvious:
akpm 1.50 | /*
akpm 1.50 | * Check to see if `name' resides inside a module which has been
akpm 1.50 | * unloaded (someone forgot to destroy their cache)
akpm 1.50 | */
Thanks to Mr. Morton for that comment. Now I get to wrestle with questions 1 and 2.
-g
>
>
>> 1. Is the ARM __get_user() broken?
>> 2. Could I be doing something else broken that is confusing __get_user()?
>> 3. What was/is the intent of the test? Or stated differently, why on earth
>> would cachep->name be a user address?
>
>
get_user is the standard test for bad pointers: If the pointer is bad,
then the exception handler will prevent an oops.
Could you backport the get_fs()/set_fs() calls around the get_user()
from 2.5? I assume that ARM needs it to distiguish between kernel and
user addresses.
On i386, it's possible to skip set_fs() and use __get_user() - but
that's i386 specific. For example the i386 oops code uses that.
--
Manfred
On Thu, Nov 28, 2002 at 11:34:20PM +0100, Manfred Spraul wrote:
> On i386, it's possible to skip set_fs() and use __get_user() - but
> that's i386 specific. For example the i386 oops code uses that.
That isn't actually an x86 specific feature - it is a requirement across
all architectures that get_user() and friends can access kernel areas
after set_fs(get_ds())
That's how things like sys_execve() can read the binary headers, etc.
See linux/fs/exec.c:kernel_read() for one such example.
--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html
Russell King wrote:
>On Thu, Nov 28, 2002 at 11:34:20PM +0100, Manfred Spraul wrote:
>
>
>>On i386, it's possible to skip set_fs() and use __get_user() - but
>>that's i386 specific. For example the i386 oops code uses that.
>>
>>
>
>That isn't actually an x86 specific feature - it is a requirement across
>all architectures that get_user() and friends can access kernel areas
>after set_fs(get_ds())
>
>
It's i386 specific that
__get_user().
is equivalent to
set_fs(KERNEL_DS)
get_user()
arch/i386/kernel/traps.c uses that in the fault code.
Portable code must use set_fs()/get_user(), i386 specific code can
continue to use __get_user().
--
Manfred
On Fri, Nov 29, 2002 at 07:24:02PM +0100, Manfred Spraul wrote:
> Russell King wrote:
> >On Thu, Nov 28, 2002 at 11:34:20PM +0100, Manfred Spraul wrote:
> >
> >
> >>On i386, it's possible to skip set_fs() and use __get_user() - but
> >>that's i386 specific. For example the i386 oops code uses that.
> >>
> >>
> >
> >That isn't actually an x86 specific feature - it is a requirement across
> >all architectures that get_user() and friends can access kernel areas
> >after set_fs(get_ds())
> >
> >
> It's i386 specific that
> __get_user().
> is equivalent to
> set_fs(KERNEL_DS)
> get_user()
> arch/i386/kernel/traps.c uses that in the fault code.
>
> Portable code must use set_fs()/get_user(), i386 specific code can
> continue to use __get_user().
That seems broken to me. IIRC, when all this uaccess stuff went in back
in 2.1 times, the original intention was that __get_user() would fault
even when used from kernel mode, unless set_fs(KERNEL_DS) was in effect.
__get_user() at that time was always meant to be used as a faster version
of get_user(), even by generic code, and relied solely on the TLB protection
mechanisms, whereas get_user() verified the address.
Gah, I _really_ wish that we had a method to notify architecture maintainers
when this type of stuff changes. Are we supposed to re-read the x86
implementation of everything for each kernel release to try to discover
what subtle semantics have changed?
--
Russell King ([email protected]) The developer of ARM Linux
http://www.arm.linux.org.uk/personal/aboutme.html
Russell King wrote:
>Gah, I _really_ wish that we had a method to notify architecture maintainers
>when this type of stuff changes. Are we supposed to re-read the x86
>implementation of everything for each kernel release to try to discover
>what subtle semantics have changed?
>
>
>
There was no change - i386 just permits something that doesn't work on
all archs.