Commit a1862e31079149a52b6223776228c3aee493d4a7

Authored by Bjorn Helgaas
Committed by Jesse Barnes
1 parent 6909ba14c2

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

... ... @@ -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;