Skip to content

Commit edce682

Browse files
jcarlyleJens Axboe
authored andcommitted
scatterlist: prevent invalid free when alloc fails
When alloc fails, free_table is being called. Depending on the number of bytes requested, we determine if we are going to call _get_free_page() or kmalloc(). When alloc fails, our math is wrong (due to sg_size - 1), and the last buffer is wrongfully assumed to have been allocated by kmalloc. Hence, kfree gets called and a panic occurs. Signed-off-by: Jeffrey Carlyle <[email protected]> Signed-off-by: Olusanya Soyannwo <[email protected]> Acked-by: Tejun Heo <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent b76b401 commit edce682

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

lib/scatterlist.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -248,8 +248,18 @@ int __sg_alloc_table(struct sg_table *table, unsigned int nents,
248248
left -= sg_size;
249249

250250
sg = alloc_fn(alloc_size, gfp_mask);
251-
if (unlikely(!sg))
252-
return -ENOMEM;
251+
if (unlikely(!sg)) {
252+
/*
253+
* Adjust entry count to reflect that the last
254+
* entry of the previous table won't be used for
255+
* linkage. Without this, sg_kfree() may get
256+
* confused.
257+
*/
258+
if (prv)
259+
table->nents = ++table->orig_nents;
260+
261+
return -ENOMEM;
262+
}
253263

254264
sg_init_table(sg, alloc_size);
255265
table->nents = table->orig_nents += sg_size;

0 commit comments

Comments
 (0)