The kernel is Linux 2.6.28.6
I had a report of a crash on mounting our UBIFS flash volume on our
m68knommu (Coldfire 5282) platform;
After tracing it down, I found this code in fs/namespace.c:
/*
* Some copy_from_user() implementations do not return the exact
number of
* bytes remaining to copy on a fault. But copy_mount_options()
requires that.
* Note that this function differs from copy_from_user() in that it
will oops
* on bad values of `to', rather than returning a short copy.
*/
static long exact_copy_from_user(void *to, const void __user * from,
unsignedlong n)
{
char *t = to;
const char __user *f = from;
char c;
if (!access_ok(VERIFY_READ, from, n))
return n;
while (n) {
if (__get_user(c, f)) {
memset(t, 0, n);
break;
}
*t++ = c;
f++;
n--;
}
return n;
}
The problem is that the from address, which is passed into the
sys_mount syscall, is within a page of the top of memory (sometimes).
Sys_mount calls copy_mount_options to copy parameters. That call
doesn't specify a length to copy - it always copies a page worth of
data. Since the source address is within a page of the top of memory,
it causes a memory fault.
On m68knommu, access_ok is a noop.
__get_user() *should* return -EFAULT on an error, but instead an
exception is raised, I think.
I was able to hack around this problem by changing the __get_user()
line to:
extern unsigned long _ramend;
if ((f >= _ramend) || __get_user(c, f)) {
Which causes the code to only copy up to the end of memory without
going over.
Does this find point to an underlying problem in __get_user() on
m68knommu?
-
allon
_______________________________________________
uClinux-dev mailing list
uClinux-dev@uclinux.org
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by uclinux-dev@uclinux.org
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev