[uClinux-dev] [PATCH] : Avoid filename < TASK_SIZE test in do_getname() when no MMU

Geert Uytterhoeven geert at linux-m68k.org
Fri May 21 01:56:00 EDT 2010


On Fri, May 21, 2010 at 00:29, Mike Frysinger <vapier at gentoo.org> wrote:
> dont know if David subscribes to this list ...

> On Thursday 20 May 2010 04:14:45 Philippe De Muyter wrote:
>> Hi Greg,
>>
>> --
>> Avoid filename < TASK_SIZE test in do_getname() when no MMU.
>>
>> Without MMU, filenames can be anywhere in memory.  It is thus wrong to
>> check that filename is before TASK_SIZE in do_getname().
>>
>> Signed-off-by: Philippe De Muyter <phdm at macqel.be>
>> ---
>>  fs/namei.c |    2 ++
>>  1 files changed, 2 insertions(+), 0 deletions(-)
>>
>> diff --git a/fs/namei.c b/fs/namei.c
>> index b86b96f..658bc1d 100644
>> --- a/fs/namei.c
>> +++ b/fs/namei.c
>> @@ -119,12 +119,14 @@ static int do_getname(const char __user *filename,
>> char *page) int retval;
>>       unsigned long len = PATH_MAX;
>>
>> +#ifdef CONFIG_MMU
>>       if (!segment_eq(get_fs(), KERNEL_DS)) {
>>               if ((unsigned long) filename >= TASK_SIZE)
>>                       return -EFAULT;
>>               if (TASK_SIZE - (unsigned long) filename < PATH_MAX)
>>                       len = TASK_SIZE - (unsigned long) filename;
>>       }
>> +#endif
>>
>>       retval = strncpy_from_user(page, filename, len);
>>       if (retval > 0) {

Are these also problematic?

m/nommu.c:static int validate_mmap_request(struct file *file,
                                 unsigned long addr,
                                 unsigned long len,
                                 unsigned long prot,
                                 unsigned long flags,
                                 unsigned long pgoff,
                                 unsigned long *_capabilities)
{
        ...
        /* Careful about overflows.. */
        rlen = PAGE_ALIGN(len);
        if (!rlen || rlen > TASK_SIZE)
                return -ENOMEM;
        ...
}

fs/namespace.c:int copy_mount_options(const void __user * data,
unsigned long *where)
{
        ...
        /* copy_from_user cannot cross TASK_SIZE ! */
        size = TASK_SIZE - (unsigned long)data;
        if (size > PAGE_SIZE)
                size = PAGE_SIZE;
        ...
}

Do we need a generic is_in_task_area() helper that always return true on nommu?

Gr{oetje,eeting}s,

						Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert at linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
							    -- Linus Torvalds



More information about the uClinux-dev mailing list