diff options
| author | Pawel Moll <pawel.moll@arm.com> | 2012-11-21 21:00:24 -0500 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2012-12-17 23:50:41 -0500 |
| commit | 40f9938c4c69183c5ceaca74b77aff636cc79623 (patch) | |
| tree | 94393c100ead39d57c4567cb9eca81fe859d72ee /drivers/virtio | |
| parent | eb34f12b509823571e88b791ae2088280943894f (diff) | |
virtio-mmio: Fix irq parsing in command line parameter
When the resource_size_t is 64-bit long, the sscanf() on
the virtio device command line paramter string may return
wrong value because its format was defined as "%u". Fixed
by using an intermediate local value of a known length.
Also added cleaned up the resource creation and added extra
comments to make the parameters parsing easier to follow.
Reported-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'drivers/virtio')
| -rw-r--r-- | drivers/virtio/virtio_mmio.c | 26 |
1 files changed, 17 insertions, 9 deletions
diff --git a/drivers/virtio/virtio_mmio.c b/drivers/virtio/virtio_mmio.c index 5a0e1d32ce13..634f80bcdbd7 100644 --- a/drivers/virtio/virtio_mmio.c +++ b/drivers/virtio/virtio_mmio.c | |||
| @@ -521,25 +521,33 @@ static int vm_cmdline_set(const char *device, | |||
| 521 | int err; | 521 | int err; |
| 522 | struct resource resources[2] = {}; | 522 | struct resource resources[2] = {}; |
| 523 | char *str; | 523 | char *str; |
| 524 | long long int base; | 524 | long long int base, size; |
| 525 | unsigned int irq; | ||
| 525 | int processed, consumed = 0; | 526 | int processed, consumed = 0; |
| 526 | struct platform_device *pdev; | 527 | struct platform_device *pdev; |
| 527 | 528 | ||
| 528 | resources[0].flags = IORESOURCE_MEM; | 529 | /* Consume "size" part of the command line parameter */ |
| 529 | resources[1].flags = IORESOURCE_IRQ; | 530 | size = memparse(device, &str); |
| 530 | |||
| 531 | resources[0].end = memparse(device, &str) - 1; | ||
| 532 | 531 | ||
| 532 | /* Get "@<base>:<irq>[:<id>]" chunks */ | ||
| 533 | processed = sscanf(str, "@%lli:%u%n:%d%n", | 533 | processed = sscanf(str, "@%lli:%u%n:%d%n", |
| 534 | &base, &resources[1].start, &consumed, | 534 | &base, &irq, &consumed, |
| 535 | &vm_cmdline_id, &consumed); | 535 | &vm_cmdline_id, &consumed); |
| 536 | 536 | ||
| 537 | if (processed < 2 || processed > 3 || str[consumed]) | 537 | /* |
| 538 | * sscanf() must processes at least 2 chunks; also there | ||
| 539 | * must be no extra characters after the last chunk, so | ||
| 540 | * str[consumed] must be '\0' | ||
| 541 | */ | ||
| 542 | if (processed < 2 || str[consumed]) | ||
| 538 | return -EINVAL; | 543 | return -EINVAL; |
| 539 | 544 | ||
| 545 | resources[0].flags = IORESOURCE_MEM; | ||
| 540 | resources[0].start = base; | 546 | resources[0].start = base; |
| 541 | resources[0].end += base; | 547 | resources[0].end = base + size - 1; |
| 542 | resources[1].end = resources[1].start; | 548 | |
| 549 | resources[1].flags = IORESOURCE_IRQ; | ||
| 550 | resources[1].start = resources[1].end = irq; | ||
| 543 | 551 | ||
| 544 | if (!vm_cmdline_parent_registered) { | 552 | if (!vm_cmdline_parent_registered) { |
| 545 | err = device_register(&vm_cmdline_parent); | 553 | err = device_register(&vm_cmdline_parent); |
