Print this page
3027 installgrub can segfault when encountering bogus data on disk


 235                 bblock->buf = NULL;
 236                 return (BC_ERROR);
 237         }
 238 
 239         dest += BBLK_DATA_RSVD_SIZE;
 240         size = bblock->buf_size - BBLK_DATA_RSVD_SIZE;
 241 
 242         if (read_in(dev_fd, dest, size, BBLK_ZFS_EXTRA_OFF) != BC_SUCCESS) {
 243                 BOOT_DEBUG("Error reading ZFS reserved area the second time\n");
 244                 (void) free(bblock->buf);
 245                 bblock->buf = NULL;
 246                 return (BC_ERROR);
 247         }
 248 
 249         /* Update pointers. */
 250         bblock->file = bblock->buf;
 251         bblock->mboot_off = mboot_off;
 252         bblock->mboot = (multiboot_header_t *)(bblock->buf + bblock->mboot_off
 253             + BBLK_DATA_RSVD_SIZE);
 254         bblock->extra = (char *)bblock->mboot + sizeof (multiboot_header_t);


 255         return (BC_SUCCESS);
 256 }
 257 
 258 static boolean_t
 259 is_update_necessary(ib_data_t *data, char *updt_str)
 260 {
 261         bblk_einfo_t    *einfo;
 262         bblk_hs_t       bblock_hs;
 263         ib_bootblock_t  bblock_disk;
 264         ib_bootblock_t  *bblock_file = &data->bootblock;
 265         ib_device_t     *device = &data->device;
 266         int             dev_fd = device->fd;
 267 
 268         assert(data != NULL);
 269         assert(device->fd != -1);
 270 
 271         /* Nothing to do if we are not updating a ZFS bootblock. */
 272         if (!is_zfs(device->type))
 273                 return (B_TRUE);
 274 
 275         bzero(&bblock_disk, sizeof (ib_bootblock_t));
 276 
 277         if (read_bootblock_from_disk(dev_fd, &bblock_disk) != BC_SUCCESS) {
 278                 BOOT_DEBUG("Unable to read bootblock from %s\n", device->path);
 279                 return (B_TRUE);
 280         }
 281 
 282         einfo = find_einfo(bblock_disk.extra);
 283         if (einfo == NULL) {
 284                 BOOT_DEBUG("No extended information available\n");
 285                 return (B_TRUE);
 286         }
 287 
 288         if (!do_version || updt_str == NULL) {
 289                 (void) fprintf(stdout, "WARNING: target device %s has a "
 290                     "versioned bootblock that is going to be overwritten by a "
 291                     "non versioned one\n", device->path);
 292                 return (B_TRUE);
 293         }
 294 
 295         if (force_update) {
 296                 BOOT_DEBUG("Forcing update of %s bootblock\n", device->path);
 297                 return (B_TRUE);
 298         }
 299 
 300         BOOT_DEBUG("Ready to check installed version vs %s\n", updt_str);
 301 
 302         bblock_hs.src_buf = (unsigned char *)bblock_file->file;


 699                 goto out_dev;
 700         }
 701 
 702         ret = read_bootblock_from_disk(device->fd, bblock);
 703         if (ret == BC_ERROR) {
 704                 (void) fprintf(stderr, gettext("Error reading bootblock from "
 705                     "%s\n"), device_path);
 706                 goto out_dev;
 707         }
 708 
 709         if (ret == BC_NOEXTRA) {
 710                 BOOT_DEBUG("No multiboot header found on %s, unable "
 711                     "to locate extra information area (old/non versioned "
 712                     "bootblock?) \n", device_path);
 713                 (void) fprintf(stderr, gettext("No extended information "
 714                     "found\n"));
 715                 retval = BC_NOEINFO;
 716                 goto out_dev;
 717         }
 718 
 719         einfo = find_einfo(bblock->extra);
 720         if (einfo == NULL) {
 721                 retval = BC_NOEINFO;
 722                 (void) fprintf(stderr, gettext("No extended information "
 723                     "found\n"));
 724                 goto out_dev;
 725         }
 726 
 727         /* Print the extended information. */
 728         if (strip)
 729                 flags |= EINFO_EASY_PARSE;
 730         if (verbose_dump)
 731                 flags |= EINFO_PRINT_HEADER;
 732 
 733         size = bblock->buf_size - P2ROUNDUP(bblock->file_size, 8) -
 734             sizeof (multiboot_header_t);
 735         print_einfo(flags, einfo, size);
 736         retval = BC_SUCCESS;
 737 
 738 out_dev:
 739         cleanup_device(&data.device);


 800                     "information from %s (attaching device)\n"),
 801                     attach_device_path);
 802                 goto out_devs;
 803         }
 804 
 805         ret = read_bootblock_from_disk(curr_device->fd, bblock_curr);
 806         if (ret == BC_ERROR) {
 807                 BOOT_DEBUG("Error reading bootblock from %s\n",
 808                     curr_device->path);
 809                 retval = BC_ERROR;
 810                 goto out_devs;
 811         }
 812 
 813         if (ret == BC_NOEXTRA) {
 814                 BOOT_DEBUG("No multiboot header found on %s, unable to retrieve"
 815                     " the bootblock\n", curr_device->path);
 816                 retval = BC_NOEXTRA;
 817                 goto out_devs;
 818         }
 819 
 820         einfo_curr = find_einfo(bblock_curr->extra);
 821         if (einfo_curr != NULL)
 822                 updt_str = einfo_get_string(einfo_curr);
 823 
 824         retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
 825         cleanup_bootblock(bblock_curr);
 826         cleanup_bootblock(bblock_attach);
 827 out_devs:
 828         cleanup_device(attach_device);
 829 out_currdev:
 830         cleanup_device(curr_device);
 831 out:
 832         free(curr_device_path);
 833         free(attach_device_path);
 834         return (retval);
 835 }
 836 
 837 #define USAGE_STRING    "Usage: %s [-h|-f|-F fstype|-u verstr] bootblk "       \
 838                         "raw-device\n"                                         \
 839                         "\t%s [-e|-V] -i -F zfs raw-device\n"                  \
 840                         "\t%s -M -F zfs raw-device attach-raw-device\n"        \




 235                 bblock->buf = NULL;
 236                 return (BC_ERROR);
 237         }
 238 
 239         dest += BBLK_DATA_RSVD_SIZE;
 240         size = bblock->buf_size - BBLK_DATA_RSVD_SIZE;
 241 
 242         if (read_in(dev_fd, dest, size, BBLK_ZFS_EXTRA_OFF) != BC_SUCCESS) {
 243                 BOOT_DEBUG("Error reading ZFS reserved area the second time\n");
 244                 (void) free(bblock->buf);
 245                 bblock->buf = NULL;
 246                 return (BC_ERROR);
 247         }
 248 
 249         /* Update pointers. */
 250         bblock->file = bblock->buf;
 251         bblock->mboot_off = mboot_off;
 252         bblock->mboot = (multiboot_header_t *)(bblock->buf + bblock->mboot_off
 253             + BBLK_DATA_RSVD_SIZE);
 254         bblock->extra = (char *)bblock->mboot + sizeof (multiboot_header_t);
 255         bblock->extra_size = bblock->buf_size - bblock->mboot_off
 256             - BBLK_DATA_RSVD_SIZE - sizeof (multiboot_header_t);
 257         return (BC_SUCCESS);
 258 }
 259 
 260 static boolean_t
 261 is_update_necessary(ib_data_t *data, char *updt_str)
 262 {
 263         bblk_einfo_t    *einfo;
 264         bblk_hs_t       bblock_hs;
 265         ib_bootblock_t  bblock_disk;
 266         ib_bootblock_t  *bblock_file = &data->bootblock;
 267         ib_device_t     *device = &data->device;
 268         int             dev_fd = device->fd;
 269 
 270         assert(data != NULL);
 271         assert(device->fd != -1);
 272 
 273         /* Nothing to do if we are not updating a ZFS bootblock. */
 274         if (!is_zfs(device->type))
 275                 return (B_TRUE);
 276 
 277         bzero(&bblock_disk, sizeof (ib_bootblock_t));
 278 
 279         if (read_bootblock_from_disk(dev_fd, &bblock_disk) != BC_SUCCESS) {
 280                 BOOT_DEBUG("Unable to read bootblock from %s\n", device->path);
 281                 return (B_TRUE);
 282         }
 283 
 284         einfo = find_einfo(bblock_disk.extra, bblock_disk.extra_size);
 285         if (einfo == NULL) {
 286                 BOOT_DEBUG("No extended information available\n");
 287                 return (B_TRUE);
 288         }
 289 
 290         if (!do_version || updt_str == NULL) {
 291                 (void) fprintf(stdout, "WARNING: target device %s has a "
 292                     "versioned bootblock that is going to be overwritten by a "
 293                     "non versioned one\n", device->path);
 294                 return (B_TRUE);
 295         }
 296 
 297         if (force_update) {
 298                 BOOT_DEBUG("Forcing update of %s bootblock\n", device->path);
 299                 return (B_TRUE);
 300         }
 301 
 302         BOOT_DEBUG("Ready to check installed version vs %s\n", updt_str);
 303 
 304         bblock_hs.src_buf = (unsigned char *)bblock_file->file;


 701                 goto out_dev;
 702         }
 703 
 704         ret = read_bootblock_from_disk(device->fd, bblock);
 705         if (ret == BC_ERROR) {
 706                 (void) fprintf(stderr, gettext("Error reading bootblock from "
 707                     "%s\n"), device_path);
 708                 goto out_dev;
 709         }
 710 
 711         if (ret == BC_NOEXTRA) {
 712                 BOOT_DEBUG("No multiboot header found on %s, unable "
 713                     "to locate extra information area (old/non versioned "
 714                     "bootblock?) \n", device_path);
 715                 (void) fprintf(stderr, gettext("No extended information "
 716                     "found\n"));
 717                 retval = BC_NOEINFO;
 718                 goto out_dev;
 719         }
 720 
 721         einfo = find_einfo(bblock->extra, bblock->extra_size);
 722         if (einfo == NULL) {
 723                 retval = BC_NOEINFO;
 724                 (void) fprintf(stderr, gettext("No extended information "
 725                     "found\n"));
 726                 goto out_dev;
 727         }
 728 
 729         /* Print the extended information. */
 730         if (strip)
 731                 flags |= EINFO_EASY_PARSE;
 732         if (verbose_dump)
 733                 flags |= EINFO_PRINT_HEADER;
 734 
 735         size = bblock->buf_size - P2ROUNDUP(bblock->file_size, 8) -
 736             sizeof (multiboot_header_t);
 737         print_einfo(flags, einfo, size);
 738         retval = BC_SUCCESS;
 739 
 740 out_dev:
 741         cleanup_device(&data.device);


 802                     "information from %s (attaching device)\n"),
 803                     attach_device_path);
 804                 goto out_devs;
 805         }
 806 
 807         ret = read_bootblock_from_disk(curr_device->fd, bblock_curr);
 808         if (ret == BC_ERROR) {
 809                 BOOT_DEBUG("Error reading bootblock from %s\n",
 810                     curr_device->path);
 811                 retval = BC_ERROR;
 812                 goto out_devs;
 813         }
 814 
 815         if (ret == BC_NOEXTRA) {
 816                 BOOT_DEBUG("No multiboot header found on %s, unable to retrieve"
 817                     " the bootblock\n", curr_device->path);
 818                 retval = BC_NOEXTRA;
 819                 goto out_devs;
 820         }
 821 
 822         einfo_curr = find_einfo(bblock_curr->extra, bblock_curr->extra_size);
 823         if (einfo_curr != NULL)
 824                 updt_str = einfo_get_string(einfo_curr);
 825 
 826         retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
 827         cleanup_bootblock(bblock_curr);
 828         cleanup_bootblock(bblock_attach);
 829 out_devs:
 830         cleanup_device(attach_device);
 831 out_currdev:
 832         cleanup_device(curr_device);
 833 out:
 834         free(curr_device_path);
 835         free(attach_device_path);
 836         return (retval);
 837 }
 838 
 839 #define USAGE_STRING    "Usage: %s [-h|-f|-F fstype|-u verstr] bootblk "       \
 840                         "raw-device\n"                                         \
 841                         "\t%s [-e|-V] -i -F zfs raw-device\n"                  \
 842                         "\t%s -M -F zfs raw-device attach-raw-device\n"        \