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


 386                 (void) fprintf(stderr, gettext("Versioning not supported on "
 387                     "PCFS\n"));
 388                 goto out_dev;
 389         }
 390 
 391         ret = read_stage2_from_disk(device->part_fd, stage2);
 392         if (ret == BC_ERROR) {
 393                 (void) fprintf(stderr, gettext("Error reading stage2 from "
 394                     "%s\n"), device_path);
 395                 goto out_dev;
 396         }
 397 
 398         if (ret == BC_NOEXTRA) {
 399                 (void) fprintf(stdout, gettext("No multiboot header found on "
 400                     "%s, unable to locate extra information area\n"),
 401                     device_path);
 402                 retval = BC_NOEINFO;
 403                 goto out_dev;
 404         }
 405 
 406         einfo = find_einfo(stage2->extra);
 407         if (einfo == NULL) {
 408                 retval = BC_NOEINFO;
 409                 (void) fprintf(stderr, gettext("No extended information "
 410                     "found\n"));
 411                 goto out_dev;
 412         }
 413 
 414         /* Print the extended information. */
 415         if (strip)
 416                 flags |= EINFO_EASY_PARSE;
 417         if (verbose_dump)
 418                 flags |= EINFO_PRINT_HEADER;
 419 
 420         size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8);
 421         print_einfo(flags, einfo, size);
 422         retval = BC_SUCCESS;
 423 
 424 out_dev:
 425         cleanup_device(&data.device);
 426 out:


 484                 (void) fprintf(stderr, gettext("boot block mirroring is not "
 485                     "supported on PCFS\n"));
 486                 goto out_devs;
 487         }
 488 
 489         ret = read_stage2_from_disk(curr_device->part_fd, stage2_curr);
 490         if (ret == BC_ERROR) {
 491                 BOOT_DEBUG("Error reading first stage2 blocks from %s\n",
 492                     curr_device->path);
 493                 retval = BC_ERROR;
 494                 goto out_devs;
 495         }
 496 
 497         if (ret == BC_NOEXTRA) {
 498                 BOOT_DEBUG("No multiboot header found on %s, unable to grab "
 499                     "stage2\n", curr_device->path);
 500                 retval = BC_NOEXTRA;
 501                 goto out_devs;
 502         }
 503 
 504         einfo_curr = find_einfo(stage2_curr->extra);
 505         if (einfo_curr != NULL)
 506                 updt_str = einfo_get_string(einfo_curr);
 507 
 508         write_mbr = B_TRUE;
 509         force_mbr = B_TRUE;
 510         retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
 511         cleanup_stage2(stage2_curr);
 512         cleanup_stage2(stage2_attach);
 513 
 514 out_devs:
 515         cleanup_device(attach_device);
 516 out_currdev:
 517         cleanup_device(curr_device);
 518 out:
 519         free(curr_device_path);
 520         free(attach_device_path);
 521         return (retval);
 522 }
 523 
 524 static int


1204         stage2->buf = malloc(buf_size);
1205         if (stage2->buf == NULL) {
1206                 perror(gettext("Memory allocation failed"));
1207                 return (BC_ERROR);
1208         }
1209         stage2->buf_size = buf_size;
1210 
1211         if (read_in(dev_fd, stage2->buf, buf_size, STAGE2_BLKOFF *
1212             SECTOR_SIZE) != BC_SUCCESS) {
1213                 perror("read");
1214                 free(stage2->buf);
1215                 return (BC_ERROR);
1216         }
1217 
1218         /* Update pointers. */
1219         stage2->file = stage2->buf;
1220         stage2->file_size = size;
1221         stage2->mboot_off = mboot_off;
1222         stage2->mboot = (multiboot_header_t *)(stage2->buf + stage2->mboot_off);
1223         stage2->extra = stage2->buf + P2ROUNDUP(stage2->file_size, 8);

1224 
1225         return (BC_SUCCESS);
1226 }
1227 
1228 static boolean_t
1229 is_update_necessary(ig_data_t *data, char *updt_str)
1230 {
1231         bblk_einfo_t    *einfo;
1232         bblk_hs_t       stage2_hs;
1233         ig_stage2_t     stage2_disk;
1234         ig_stage2_t     *stage2_file = &data->stage2;
1235         ig_device_t     *device = &data->device;
1236         int             dev_fd = device->part_fd;
1237 
1238         assert(data != NULL);
1239         assert(device->part_fd != -1);
1240 
1241         bzero(&stage2_disk, sizeof (ig_stage2_t));
1242 
1243         /* Gather stage2 (if present) from the target device. */
1244         if (read_stage2_from_disk(dev_fd, &stage2_disk) != BC_SUCCESS) {
1245                 BOOT_DEBUG("Unable to read stage2 from %s\n", device->path);
1246                 BOOT_DEBUG("No multiboot wrapped stage2 on %s\n", device->path);
1247                 return (B_TRUE);
1248         }
1249 
1250         /*
1251          * Look for the extended information structure in the extra payload
1252          * area.
1253          */
1254         einfo = find_einfo(stage2_disk.extra);
1255         if (einfo == NULL) {
1256                 BOOT_DEBUG("No extended information available\n");
1257                 return (B_TRUE);
1258         }
1259 
1260         if (!do_version || updt_str == NULL) {
1261                 (void) fprintf(stdout, "WARNING: target device %s has a "
1262                     "versioned stage2 that is going to be overwritten by a non "
1263                     "versioned one\n", device->path);
1264                 return (B_TRUE);
1265         }
1266 
1267         if (force_update) {
1268                 BOOT_DEBUG("Forcing update of %s bootblock\n", device->path);
1269                 return (B_TRUE);
1270         }
1271 
1272         /* Compare the two extended information structures. */
1273         stage2_hs.src_buf = (unsigned char *)stage2_file->file;
1274         stage2_hs.src_size = stage2_file->file_size;




 386                 (void) fprintf(stderr, gettext("Versioning not supported on "
 387                     "PCFS\n"));
 388                 goto out_dev;
 389         }
 390 
 391         ret = read_stage2_from_disk(device->part_fd, stage2);
 392         if (ret == BC_ERROR) {
 393                 (void) fprintf(stderr, gettext("Error reading stage2 from "
 394                     "%s\n"), device_path);
 395                 goto out_dev;
 396         }
 397 
 398         if (ret == BC_NOEXTRA) {
 399                 (void) fprintf(stdout, gettext("No multiboot header found on "
 400                     "%s, unable to locate extra information area\n"),
 401                     device_path);
 402                 retval = BC_NOEINFO;
 403                 goto out_dev;
 404         }
 405 
 406         einfo = find_einfo(stage2->extra, stage2->extra_size);
 407         if (einfo == NULL) {
 408                 retval = BC_NOEINFO;
 409                 (void) fprintf(stderr, gettext("No extended information "
 410                     "found\n"));
 411                 goto out_dev;
 412         }
 413 
 414         /* Print the extended information. */
 415         if (strip)
 416                 flags |= EINFO_EASY_PARSE;
 417         if (verbose_dump)
 418                 flags |= EINFO_PRINT_HEADER;
 419 
 420         size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8);
 421         print_einfo(flags, einfo, size);
 422         retval = BC_SUCCESS;
 423 
 424 out_dev:
 425         cleanup_device(&data.device);
 426 out:


 484                 (void) fprintf(stderr, gettext("boot block mirroring is not "
 485                     "supported on PCFS\n"));
 486                 goto out_devs;
 487         }
 488 
 489         ret = read_stage2_from_disk(curr_device->part_fd, stage2_curr);
 490         if (ret == BC_ERROR) {
 491                 BOOT_DEBUG("Error reading first stage2 blocks from %s\n",
 492                     curr_device->path);
 493                 retval = BC_ERROR;
 494                 goto out_devs;
 495         }
 496 
 497         if (ret == BC_NOEXTRA) {
 498                 BOOT_DEBUG("No multiboot header found on %s, unable to grab "
 499                     "stage2\n", curr_device->path);
 500                 retval = BC_NOEXTRA;
 501                 goto out_devs;
 502         }
 503 
 504         einfo_curr = find_einfo(stage2_curr->extra, stage2_curr->extra_size);
 505         if (einfo_curr != NULL)
 506                 updt_str = einfo_get_string(einfo_curr);
 507 
 508         write_mbr = B_TRUE;
 509         force_mbr = B_TRUE;
 510         retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
 511         cleanup_stage2(stage2_curr);
 512         cleanup_stage2(stage2_attach);
 513 
 514 out_devs:
 515         cleanup_device(attach_device);
 516 out_currdev:
 517         cleanup_device(curr_device);
 518 out:
 519         free(curr_device_path);
 520         free(attach_device_path);
 521         return (retval);
 522 }
 523 
 524 static int


1204         stage2->buf = malloc(buf_size);
1205         if (stage2->buf == NULL) {
1206                 perror(gettext("Memory allocation failed"));
1207                 return (BC_ERROR);
1208         }
1209         stage2->buf_size = buf_size;
1210 
1211         if (read_in(dev_fd, stage2->buf, buf_size, STAGE2_BLKOFF *
1212             SECTOR_SIZE) != BC_SUCCESS) {
1213                 perror("read");
1214                 free(stage2->buf);
1215                 return (BC_ERROR);
1216         }
1217 
1218         /* Update pointers. */
1219         stage2->file = stage2->buf;
1220         stage2->file_size = size;
1221         stage2->mboot_off = mboot_off;
1222         stage2->mboot = (multiboot_header_t *)(stage2->buf + stage2->mboot_off);
1223         stage2->extra = stage2->buf + P2ROUNDUP(stage2->file_size, 8);
1224         stage2->extra_size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8);
1225 
1226         return (BC_SUCCESS);
1227 }
1228 
1229 static boolean_t
1230 is_update_necessary(ig_data_t *data, char *updt_str)
1231 {
1232         bblk_einfo_t    *einfo;
1233         bblk_hs_t       stage2_hs;
1234         ig_stage2_t     stage2_disk;
1235         ig_stage2_t     *stage2_file = &data->stage2;
1236         ig_device_t     *device = &data->device;
1237         int             dev_fd = device->part_fd;
1238 
1239         assert(data != NULL);
1240         assert(device->part_fd != -1);
1241 
1242         bzero(&stage2_disk, sizeof (ig_stage2_t));
1243 
1244         /* Gather stage2 (if present) from the target device. */
1245         if (read_stage2_from_disk(dev_fd, &stage2_disk) != BC_SUCCESS) {
1246                 BOOT_DEBUG("Unable to read stage2 from %s\n", device->path);
1247                 BOOT_DEBUG("No multiboot wrapped stage2 on %s\n", device->path);
1248                 return (B_TRUE);
1249         }
1250 
1251         /*
1252          * Look for the extended information structure in the extra payload
1253          * area.
1254          */
1255         einfo = find_einfo(stage2_disk.extra, stage2_disk.extra_size);
1256         if (einfo == NULL) {
1257                 BOOT_DEBUG("No extended information available\n");
1258                 return (B_TRUE);
1259         }
1260 
1261         if (!do_version || updt_str == NULL) {
1262                 (void) fprintf(stdout, "WARNING: target device %s has a "
1263                     "versioned stage2 that is going to be overwritten by a non "
1264                     "versioned one\n", device->path);
1265                 return (B_TRUE);
1266         }
1267 
1268         if (force_update) {
1269                 BOOT_DEBUG("Forcing update of %s bootblock\n", device->path);
1270                 return (B_TRUE);
1271         }
1272 
1273         /* Compare the two extended information structures. */
1274         stage2_hs.src_buf = (unsigned char *)stage2_file->file;
1275         stage2_hs.src_size = stage2_file->file_size;