Commit a1862e31079149a52b6223776228c3aee493d4a7
Committed by
Jesse Barnes
1 parent
6909ba14c2
Exists in
master
and in
4 other branches
resources: handle overflow when aligning start of available area
If tmp.start is near ~0, ALIGN(tmp.start) may overflow, which would make us think there's more available space than there really is. We would likely return something that conflicts with a previous resource, which would cause a failure when allocate_resource() requests the newly- allocated region. Reference: https://bugzilla.redhat.com/show_bug.cgi?id=646027 Reported-by: Fabrice Bellet <fabrice@bellet.info> Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com> Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Showing 1 changed file with 13 additions and 8 deletions Side-by-side Diff
kernel/resource.c
... | ... | @@ -392,7 +392,7 @@ |
392 | 392 | void *alignf_data) |
393 | 393 | { |
394 | 394 | struct resource *this = root->child; |
395 | - struct resource tmp = *new, alloc; | |
395 | + struct resource tmp = *new, avail, alloc; | |
396 | 396 | |
397 | 397 | tmp.start = root->start; |
398 | 398 | /* |
399 | 399 | |
... | ... | @@ -410,14 +410,19 @@ |
410 | 410 | tmp.end = root->end; |
411 | 411 | |
412 | 412 | resource_clip(&tmp, min, max); |
413 | - tmp.start = ALIGN(tmp.start, align); | |
414 | 413 | |
415 | - alloc.start = alignf(alignf_data, &tmp, size, align); | |
416 | - alloc.end = alloc.start + size - 1; | |
417 | - if (resource_contains(&tmp, &alloc)) { | |
418 | - new->start = alloc.start; | |
419 | - new->end = alloc.end; | |
420 | - return 0; | |
414 | + /* Check for overflow after ALIGN() */ | |
415 | + avail = *new; | |
416 | + avail.start = ALIGN(tmp.start, align); | |
417 | + avail.end = tmp.end; | |
418 | + if (avail.start >= tmp.start) { | |
419 | + alloc.start = alignf(alignf_data, &avail, size, align); | |
420 | + alloc.end = alloc.start + size - 1; | |
421 | + if (resource_contains(&avail, &alloc)) { | |
422 | + new->start = alloc.start; | |
423 | + new->end = alloc.end; | |
424 | + return 0; | |
425 | + } | |
421 | 426 | } |
422 | 427 | if (!this) |
423 | 428 | break; |