unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned
long len,
unsigned long prot, unsigned long flags, unsigned long pgoff)
{
[local var defs snipped]
if (file && (!file->f_op || !file->f_op->mmap))
return -ENODEV;
if ((len = PAGE_ALIGN(len)) == 0)
return addr;
if (len > TASK_SIZE)
return -EINVAL;
/* offset overflow? */
if ((pgoff + (len >> PAGE_SHIFT)) < pgoff)
return -EINVAL;
...
> The matter is that mmap() doesn't fail with values of
> SIZE_MAX-4095 and higher (as it should do), but succeeds returning
> '0' as the address... This is due the calculus that PAGE_ALIGN does
> with the enormous length passed (namely 4294963200 or higher, up to
> the limit marked by SIZE_MAX: 2^32-1). This macro cannot be used with
> numbers near to the limit. mmap() should return -1 and set errno to
> EINVAL, as properly does when the enormous length is less than
> 2^32-4096.
So,
- if ((len = PAGE_ALIGN(len)) == 0)
- return addr;
- if (len > TASK_SIZE)
+ if (!len)
+ return addr;
+ len = PAGE_ALIGN(len);
+ if (!len || len > TASK_SIZE) /* !len: address wrapped to 0 in ALIGN */
> I know: this lengths are enormous, nobody uses them, etc... but I
Looks like you found an obscure corner case. Good!
> think that mmap shouldn't behave as bad just because nobody will use
> the entire domain of the function. If the length domain is [0, 2^32)
> the function should behave correctly, returning errors as
> appropriate, not succeeding falsely. So please consider correcting
> the problem (should suffice with eliminating the use of PAGE_ALIGN or
> adding special cases to the test prior to its use).
>
> If this is not a bug, but an intended behaviour please excuse me.
> Moreover, I can provide a patch (I suppose) against the 2.4.18 tree.
Do it.
BTW, does anybody know why len==0 is not flagged as error?
-- vda - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/