Le 02/02/2014 05:35, Emmanuel Dreyfus a écrit :
[snip] + int count = SCARG(uap, misc); + int i, error = 0; + + /* Make sure userland cannot exhaust kernel memory */ + if ((size_t)count > (size_t)uvmexp.nswapdev) + count = uvmexp.nswapdev; + + sep = kmem_alloc(sizeof(*sep) * count, KM_SLEEP); + sep32 = kmem_alloc(sizeof(*sep32) * count, KM_SLEEP); + + uvm_swap_stats(SWAP_STATS, sep, count, retval); + count = *retval; + + if (count < 1) + goto out; + + for (i = 0; i < count; i++) { + sep32[i].se_dev = sep[i].se_dev; + sep32[i].se_flags = sep[i].se_flags; + sep32[i].se_nblks = sep[i].se_nblks; + sep32[i].se_inuse = sep[i].se_inuse; + sep32[i].se_priority = sep[i].se_priority; + memcpy(sep32[i].se_path, sep[i].se_path, + sizeof(sep32[i].se_path)); + }
I don't think that nswapdev can go ridiculously high anyway, however I think that the bound checks for "count" does prevent kernel memory exhaustion but not corruption.
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.
Cheers, -- Jean-Yves Migeon