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

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/boot/installgrub/installgrub.c
          +++ new/usr/src/cmd/boot/installgrub/installgrub.c
↓ open down ↓ 395 lines elided ↑ open up ↑
 396  396          }
 397  397  
 398  398          if (ret == BC_NOEXTRA) {
 399  399                  (void) fprintf(stdout, gettext("No multiboot header found on "
 400  400                      "%s, unable to locate extra information area\n"),
 401  401                      device_path);
 402  402                  retval = BC_NOEINFO;
 403  403                  goto out_dev;
 404  404          }
 405  405  
 406      -        einfo = find_einfo(stage2->extra);
      406 +        einfo = find_einfo(stage2->extra, stage2->extra_size);
 407  407          if (einfo == NULL) {
 408  408                  retval = BC_NOEINFO;
 409  409                  (void) fprintf(stderr, gettext("No extended information "
 410  410                      "found\n"));
 411  411                  goto out_dev;
 412  412          }
 413  413  
 414  414          /* Print the extended information. */
 415  415          if (strip)
 416  416                  flags |= EINFO_EASY_PARSE;
↓ open down ↓ 77 lines elided ↑ open up ↑
 494  494                  goto out_devs;
 495  495          }
 496  496  
 497  497          if (ret == BC_NOEXTRA) {
 498  498                  BOOT_DEBUG("No multiboot header found on %s, unable to grab "
 499  499                      "stage2\n", curr_device->path);
 500  500                  retval = BC_NOEXTRA;
 501  501                  goto out_devs;
 502  502          }
 503  503  
 504      -        einfo_curr = find_einfo(stage2_curr->extra);
      504 +        einfo_curr = find_einfo(stage2_curr->extra, stage2_curr->extra_size);
 505  505          if (einfo_curr != NULL)
 506  506                  updt_str = einfo_get_string(einfo_curr);
 507  507  
 508  508          write_mbr = B_TRUE;
 509  509          force_mbr = B_TRUE;
 510  510          retval = propagate_bootblock(&curr_data, &attach_data, updt_str);
 511  511          cleanup_stage2(stage2_curr);
 512  512          cleanup_stage2(stage2_attach);
 513  513  
 514  514  out_devs:
↓ open down ↓ 699 lines elided ↑ open up ↑
1214 1214                  free(stage2->buf);
1215 1215                  return (BC_ERROR);
1216 1216          }
1217 1217  
1218 1218          /* Update pointers. */
1219 1219          stage2->file = stage2->buf;
1220 1220          stage2->file_size = size;
1221 1221          stage2->mboot_off = mboot_off;
1222 1222          stage2->mboot = (multiboot_header_t *)(stage2->buf + stage2->mboot_off);
1223 1223          stage2->extra = stage2->buf + P2ROUNDUP(stage2->file_size, 8);
     1224 +        stage2->extra_size = stage2->buf_size - P2ROUNDUP(stage2->file_size, 8);
1224 1225  
1225 1226          return (BC_SUCCESS);
1226 1227  }
1227 1228  
1228 1229  static boolean_t
1229 1230  is_update_necessary(ig_data_t *data, char *updt_str)
1230 1231  {
1231 1232          bblk_einfo_t    *einfo;
1232 1233          bblk_hs_t       stage2_hs;
1233 1234          ig_stage2_t     stage2_disk;
↓ open down ↓ 10 lines elided ↑ open up ↑
1244 1245          if (read_stage2_from_disk(dev_fd, &stage2_disk) != BC_SUCCESS) {
1245 1246                  BOOT_DEBUG("Unable to read stage2 from %s\n", device->path);
1246 1247                  BOOT_DEBUG("No multiboot wrapped stage2 on %s\n", device->path);
1247 1248                  return (B_TRUE);
1248 1249          }
1249 1250  
1250 1251          /*
1251 1252           * Look for the extended information structure in the extra payload
1252 1253           * area.
1253 1254           */
1254      -        einfo = find_einfo(stage2_disk.extra);
     1255 +        einfo = find_einfo(stage2_disk.extra, stage2_disk.extra_size);
1255 1256          if (einfo == NULL) {
1256 1257                  BOOT_DEBUG("No extended information available\n");
1257 1258                  return (B_TRUE);
1258 1259          }
1259 1260  
1260 1261          if (!do_version || updt_str == NULL) {
1261 1262                  (void) fprintf(stdout, "WARNING: target device %s has a "
1262 1263                      "versioned stage2 that is going to be overwritten by a non "
1263 1264                      "versioned one\n", device->path);
1264 1265                  return (B_TRUE);
↓ open down ↓ 301 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX