Isaku Yamahata wrote:
> Hi.
> Recently I twisted the xen xm dump-core format so that the section
> order was changed for optimization.
> Although it shouldn't affect analysis tools, it revealed a bug.
> The crash utility tries to read the file beyond EOF.
> So far it wasn't issue because of section ordering.
> This patch fixes it by calculating read size correctly
>
The crash patch looks reasonable. But when you state that
"So far it wasn't issue because of section ordering", it
would seem that just the opposite would be true? Since the
.xen_pages section has been moved closer to the beginning
of the dumpfile, it would seem that the EOF read error would
be *more likely* when using the older dumpfile format, where
the .xen_pages section was located closer to the end of the
dumpfile?
Sorry -- I misunderstood -- it's not the .xen_pages data
that it's reading, but rather the p2m list.
The patch looks good... ;-)
> Dave, Although I don't think that it causes serious issues,
> Could you check whether the minor update of the format affects
> the crash utility?
>
http://article.gmane.org/gmane.comp.emulators.xen.ia64/7531
>
http://article.gmane.org/gmane.comp.emulators.xen.devel/42996
You'd have to make some sample dumpfiles available to me
to verify the new format.
I'm more concerned at the moment for backwards-compatibility, i.e.,
whether the crash patch will still work OK with the "older" xen
ELF core format, which will be used in the RHEL5.1 update,
and possibly beyond that.
Thanks,
Dave
>
>
> --- crash-4.0-4.6-ORIG/xendump.c 2007-08-28 00:51:11.000000000 +0900
> +++ ./crash-4.0-4.6/xendump.c 2007-08-29 18:14:05.000000000 +0900
> @@ -1289,9 +1289,8 @@ xc_core_mfn_to_page(ulong mfn, char *pgb
>
> for (b = 0, idx = -1, done = FALSE; !done && (b <
> nr_pages); b += MAX_BATCH_SIZE) {
> -
> - if (read(xd->xfd, tmp, sizeof(ulong) *
> MAX_BATCH_SIZE) != - (MAX_BATCH_SIZE * sizeof(ulong))) {
> + size_t size = sizeof(ulong) * MIN(MAX_BATCH_SIZE, nr_pages - b);
> + if (read(xd->xfd, tmp, size) != size) {
> error(INFO, "cannot read index page %d\n", b);
> return NULL;
> }
> @@ -1348,13 +1347,11 @@ xc_core_elf_mfn_to_page(ulong mfn, char {
> int i, b, idx, done;
> off_t offset;
> - size_t size;
> uint nr_pages;
> ulong tmp;
> struct xen_dumpcore_p2m p2m_batch[MAX_BATCH_SIZE];
>
> offset = xd->xc_core.header.xch_index_offset;
> - size = sizeof(struct xen_dumpcore_p2m) * MAX_BATCH_SIZE;
> nr_pages = xd->xc_core.header.xch_nr_pages;
>
> if (lseek(xd->xfd, offset, SEEK_SET) == -1)
> @@ -1362,7 +1359,8 @@ xc_core_elf_mfn_to_page(ulong mfn, char
> for (b = 0, idx = -1, done = FALSE; !done && (b <
> nr_pages); b += MAX_BATCH_SIZE) {
> -
> + size_t size = sizeof(struct xen_dumpcore_p2m) *
> + MIN(MAX_BATCH_SIZE, nr_pages - b);
> if (read(xd->xfd, &p2m_batch[0], size) != size) {
> error(INFO, "cannot read index page %d\n", b);
> return NULL;
> @@ -1437,9 +1435,9 @@ xc_core_mfn_to_page_index(ulong mfn)
> nr_pages *= 2;
>
> for (b = 0; b < nr_pages; b += MAX_BATCH_SIZE) {
> -
> - if (read(xd->xfd, tmp, sizeof(ulong) *
> MAX_BATCH_SIZE) != - (MAX_BATCH_SIZE * sizeof(ulong))) {
> + size_t size =
> + sizeof(ulong) * MIN(MAX_BATCH_SIZE, nr_pages - b);
> + if (read(xd->xfd, tmp, size) != size) {
> error(INFO, "cannot read index page %d\n", b);
> return MFN_NOT_FOUND;
> }
> @@ -1469,20 +1467,19 @@ xc_core_elf_mfn_to_page_index(ulong mfn)
> {
> int i, b;
> off_t offset;
> - size_t size;
> uint nr_pages;
> ulong tmp;
> struct xen_dumpcore_p2m p2m_batch[MAX_BATCH_SIZE];
>
> offset = xd->xc_core.header.xch_index_offset;
> - size = sizeof(struct xen_dumpcore_p2m) * MAX_BATCH_SIZE;
> nr_pages = xd->xc_core.header.xch_nr_pages;
>
> if (lseek(xd->xfd, offset, SEEK_SET) == -1)
> error(FATAL, "cannot lseek to page index\n");
>
> for (b = 0; b < nr_pages; b += MAX_BATCH_SIZE) {
> -
> + size_t size = sizeof(struct xen_dumpcore_p2m) *
> + MIN(MAX_BATCH_SIZE, nr_pages - b);
> if (read(xd->xfd, &p2m_batch[0], size) != size) {
> error(INFO, "cannot read index page %d\n", b);
> return MFN_NOT_FOUND;
> @@ -1563,8 +1560,9 @@ check_next_4:
> nr_pages = xd->xc_core.header.xch_nr_pages;
>
> for (b = 0; b < nr_pages; b += MAX_BATCH_SIZE) {
> - if (read(xd->xfd, tmp, sizeof(ulong) *
> MAX_BATCH_SIZE) !=
> - (MAX_BATCH_SIZE * sizeof(ulong))) {
> + size_t size = sizeof(ulong) *
> + MIN(MAX_BATCH_SIZE, nr_pages - b);
> + if (read(xd->xfd, tmp, size) != size) {
> error(INFO, "cannot read index page
> %d\n", b);
> return FALSE;
> }
> @@ -1595,8 +1593,9 @@ show_64bit_mfns:
> nr_pages = xd->xc_core.header.xch_nr_pages;
>
> for (b = 0; b < nr_pages; b += MAX_BATCH_SIZE) {
> - if (read(xd->xfd, tmp64, sizeof(ulonglong) *
> MAX_BATCH_SIZE) !=
> - (MAX_BATCH_SIZE * sizeof(ulonglong))) {
> + size_t size = sizeof(ulonglong) *
> + MIN(MAX_BATCH_SIZE, nr_pages - b);
> + if (read(xd->xfd, tmp64, size) != size) {
> error(INFO, "cannot read index page
> %d\n", b);
> return FALSE;
> }
> @@ -1709,13 +1708,11 @@ xc_core_elf_pfn_to_page_index(ulong pfn)
> {
> int i, b, start_index;
> off_t offset;
> - size_t size;
> uint nr_pages;
> ulong tmp;
> struct xen_dumpcore_p2m p2m_batch[MAX_BATCH_SIZE];
>
> offset = xd->xc_core.header.xch_index_offset;
> - size = sizeof(struct xen_dumpcore_p2m) * MAX_BATCH_SIZE;
> nr_pages = xd->xc_core.header.xch_nr_pages;
>
> /*
> @@ -1744,7 +1741,8 @@ xc_core_elf_pfn_to_page_index(ulong pfn)
> error(FATAL, "cannot lseek to page index\n");
>
> for (b = start_index; b < nr_pages; b += MAX_BATCH_SIZE) {
> -
> + size_t size = sizeof(struct xen_dumpcore_p2m) *
> + MIN(MAX_BATCH_SIZE, nr_pages - b);
> if (read(xd->xfd, &p2m_batch[0], size) != size) {
> error(INFO, "cannot read index page %d\n", b);
> return PFN_NOT_FOUND;
> @@ -1838,13 +1836,11 @@ xc_core_elf_pfn_valid(ulong pfn)
> {
> int i, b, start_index;
> off_t offset;
> - size_t size;
> uint nr_pages;
> ulong tmp;
> uint64_t pfn_batch[MAX_BATCH_SIZE];
>
> offset = xd->xc_core.header.xch_index_offset;
> - size = sizeof(uint64_t) * MAX_BATCH_SIZE;
> nr_pages = xd->xc_core.header.xch_nr_pages;
>
> /*
> @@ -1873,7 +1869,8 @@ xc_core_elf_pfn_valid(ulong pfn)
> error(FATAL, "cannot lseek to page index\n");
>
> for (b = start_index; b < nr_pages; b += MAX_BATCH_SIZE) {
> -
> + size_t size = sizeof(uint64_t) *
> + MIN(MAX_BATCH_SIZE, nr_pages - b);
> if (read(xd->xfd, &pfn_batch[0], size) != size) {
> error(INFO, "cannot read index page %d\n", b);
> return PFN_NOT_FOUND;
>