Skip to content

Commit

Permalink
resource: fix integer overflow at reallocation
Browse files Browse the repository at this point in the history
We've got a bug report indicating a kernel panic at booting on an x86-32
system, and it turned out to be the invalid PCI resource assigned after
reallocation.  __find_resource() first aligns the resource start address
and resets the end address with start+size-1 accordingly, then checks
whether it's contained.  Here the end address may overflow the integer,
although resource_contains() still returns true because the function
validates only start and end address.  So this ends up with returning an
invalid resource (start > end).

There was already an attempt to cover such a problem in the commit
47ea91b ("Resource: fix wrong resource window calculation"), but
this case is an overseen one.

This patch adds the validity check of the newly calculated resource for
avoiding the integer overflow problem.

Bugzilla: http://bugzilla.opensuse.org/show_bug.cgi?id=1086739
Link: http://lkml.kernel.org/r/[email protected]
Fixes: 23c570a ("resource: ability to resize an allocated resource")
Signed-off-by: Takashi Iwai <[email protected]>
Reported-by: Michael Henders <[email protected]>
Tested-by: Michael Henders <[email protected]>
Reviewed-by: Andrew Morton <[email protected]>
Cc: Ram Pai <[email protected]>
Cc: Bjorn Helgaas <[email protected]>
Cc: <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
  • Loading branch information
tiwai authored and torvalds committed Apr 14, 2018
1 parent 16e205c commit 60bb83b
Showing 1 changed file with 2 additions and 1 deletion.
3 changes: 2 additions & 1 deletion kernel/resource.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,7 +651,8 @@ static int __find_resource(struct resource *root, struct resource *old,
alloc.start = constraint->alignf(constraint->alignf_data, &avail,
size, constraint->align);
alloc.end = alloc.start + size - 1;
if (resource_contains(&avail, &alloc)) {
if (alloc.start <= alloc.end &&
resource_contains(&avail, &alloc)) {
new->start = alloc.start;
new->end = alloc.end;
return 0;
Expand Down

0 comments on commit 60bb83b

Please sign in to comment.