diff options
-rw-r--r-- | drivers/block/rbd.c | 28 |
1 files changed, 15 insertions, 13 deletions
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index e5eaa70e8826..2a94f8e81f67 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -494,17 +494,21 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
494 | u32 allocated_snaps) | 494 | u32 allocated_snaps) |
495 | { | 495 | { |
496 | u32 snap_count; | 496 | u32 snap_count; |
497 | size_t size; | ||
497 | 498 | ||
498 | if (!rbd_dev_ondisk_valid(ondisk)) | 499 | if (!rbd_dev_ondisk_valid(ondisk)) |
499 | return -ENXIO; | 500 | return -ENXIO; |
500 | 501 | ||
501 | snap_count = le32_to_cpu(ondisk->snap_count); | 502 | snap_count = le32_to_cpu(ondisk->snap_count); |
502 | if (snap_count > (SIZE_MAX - sizeof(struct ceph_snap_context)) | 503 | |
503 | / sizeof (u64)) | 504 | /* Make sure we don't overflow below */ |
505 | size = SIZE_MAX - sizeof (struct ceph_snap_context); | ||
506 | if (snap_count > size / sizeof (header->snapc->snaps[0])) | ||
504 | return -EINVAL; | 507 | return -EINVAL; |
505 | header->snapc = kmalloc(sizeof(struct ceph_snap_context) + | 508 | |
506 | snap_count * sizeof(u64), | 509 | size = sizeof (struct ceph_snap_context); |
507 | GFP_KERNEL); | 510 | size += snap_count * sizeof (header->snapc->snaps[0]); |
511 | header->snapc = kmalloc(size, GFP_KERNEL); | ||
508 | if (!header->snapc) | 512 | if (!header->snapc) |
509 | return -ENOMEM; | 513 | return -ENOMEM; |
510 | 514 | ||
@@ -515,8 +519,8 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
515 | GFP_KERNEL); | 519 | GFP_KERNEL); |
516 | if (!header->snap_names) | 520 | if (!header->snap_names) |
517 | goto err_snapc; | 521 | goto err_snapc; |
518 | header->snap_sizes = kmalloc(snap_count * sizeof(u64), | 522 | size = snap_count * sizeof (*header->snap_sizes); |
519 | GFP_KERNEL); | 523 | header->snap_sizes = kmalloc(size, GFP_KERNEL); |
520 | if (!header->snap_sizes) | 524 | if (!header->snap_sizes) |
521 | goto err_names; | 525 | goto err_names; |
522 | } else { | 526 | } else { |
@@ -526,14 +530,12 @@ static int rbd_header_from_disk(struct rbd_image_header *header, | |||
526 | header->snap_sizes = NULL; | 530 | header->snap_sizes = NULL; |
527 | } | 531 | } |
528 | 532 | ||
529 | header->object_prefix = kmalloc(sizeof (ondisk->block_name) + 1, | 533 | size = sizeof (ondisk->block_name) + 1; |
530 | GFP_KERNEL); | 534 | header->object_prefix = kmalloc(size, GFP_KERNEL); |
531 | if (!header->object_prefix) | 535 | if (!header->object_prefix) |
532 | goto err_sizes; | 536 | goto err_sizes; |
533 | 537 | memcpy(header->object_prefix, ondisk->block_name, size - 1); | |
534 | memcpy(header->object_prefix, ondisk->block_name, | 538 | header->object_prefix[size - 1] = '\0'; |
535 | sizeof(ondisk->block_name)); | ||
536 | header->object_prefix[sizeof (ondisk->block_name)] = '\0'; | ||
537 | 539 | ||
538 | header->image_size = le64_to_cpu(ondisk->image_size); | 540 | header->image_size = le64_to_cpu(ondisk->image_size); |
539 | header->obj_order = ondisk->options.order; | 541 | header->obj_order = ondisk->options.order; |