On some architectures, mapping the scatterlist may coalesce entries:
if that coalesced list is then used for freeing the pages afterwards,
there's a danger that pages may be doubly freed (and others leaked).
Fix Power RAID's ipr_free_ucode_buffer by freeing from a separate array
beyond the scatterlist.
Signed-off-by: Hugh Dickins <[email protected]>
---
Warning: untested!
drivers/scsi/ipr.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
--- 2.6.16-rc2/drivers/scsi/ipr.c 2006-02-03 09:32:24.000000000 +0000
+++ linux/drivers/scsi/ipr.c 2006-02-03 09:59:37.000000000 +0000
@@ -2538,6 +2538,7 @@ static struct ipr_sglist *ipr_alloc_ucod
int sg_size, order, bsize_elem, num_elem, i, j;
struct ipr_sglist *sglist;
struct scatterlist *scatterlist;
+ struct page **sg_pages;
struct page *page;
/* Get the minimum size per scatter/gather element */
@@ -2557,7 +2558,8 @@ static struct ipr_sglist *ipr_alloc_ucod
/* Allocate a scatter/gather list for the DMA */
sglist = kzalloc(sizeof(struct ipr_sglist) +
- (sizeof(struct scatterlist) * (num_elem - 1)),
+ (sizeof(struct scatterlist) * (num_elem - 1)) +
+ (sizeof(struct page *) * num_elem),
GFP_KERNEL);
if (sglist == NULL) {
@@ -2566,6 +2568,8 @@ static struct ipr_sglist *ipr_alloc_ucod
}
scatterlist = sglist->scatterlist;
+ /* Save pages to be freed in array beyond scatterlist */
+ sg_pages = (struct page **) (scatterlist + num_elem);
sglist->order = order;
sglist->num_sg = num_elem;
@@ -2584,6 +2588,7 @@ static struct ipr_sglist *ipr_alloc_ucod
}
scatterlist[i].page = page;
+ sg_pages[i] = page;
}
return sglist;
@@ -2601,10 +2606,13 @@ static struct ipr_sglist *ipr_alloc_ucod
**/
static void ipr_free_ucode_buffer(struct ipr_sglist *sglist)
{
+ struct page **sg_pages;
int i;
+ /* Scatterlist entries may have been coalesced: free saved pagelist */
+ sg_pages = (struct page **) (sglist->scatterlist + sglist->num_sg);
for (i = 0; i < sglist->num_sg; i++)
- __free_pages(sglist->scatterlist[i].page, sglist->order);
+ __free_pages(sg_pages[i], sglist->order);
kfree(sglist);
}
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
[Index of Archives]
[Kernel Newbies]
[Netfilter]
[Bugtraq]
[Photo]
[Stuff]
[Gimp]
[Yosemite News]
[MIPS Linux]
[ARM Linux]
[Linux Security]
[Linux RAID]
[Video 4 Linux]
[Linux for the blind]
[Linux Resources]