Le 02/02/2014 16:04, Taylor R Campbell a écrit :
Date: Mon, 03 Feb 2014 00:37:34 +1100
from: matthew green <m...@eterna.com.au>
> > + sep = kmem_alloc(sizeof(*sep) * count, KM_SLEEP);
> > + sep32 = kmem_alloc(sizeof(*sep32) * count, KM_SLEEP);
>
> You can overflow "sizeof(*sep) * count", make the kmem_alloc(...)
> succeed (the overflow will result in a small size_t if "count" is
> properly chosen which is the size kmem_alloc() expects), then corrupt
> adjacent kernel memory through the loop when writing into sep32 array.
it would require having about 4 million swap devices to trigger this.
... nothing to see here, move right along. :-)
Nevertheless, it wouldn't hurt to add
if (count > (SIZE_MAX / sizeof(*sep))) fail;
if (count > (SIZE_MAX / sizeof(*sep32))) fail;
IMHO these kind of checks should always be present at kernel/userland or
kernel/network transitions. They are often overly paranoid but help
avoids unwanted overflows that get exploited sooner or later.
or perhaps to introduce a kmem_calloc which would do this check for
us, and that way you could eyeball the code locally to verify its
safety without having to reason about the context.
Difficult. The overflow happens before kmem_alloc() is called, function
has no visibility unless played with dirty tricks with compiler and macros.
Even functions like calloc(3) are not required to check for the overflow
themselves when you pass them (number of elements, sizeof elements).
Overflow checks are rather cumbersome in C...
https://www.securecoding.cert.org/confluence/display/seccode/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
--
Jean-Yves Migeon