[Libguestfs] [PATCH v2 1/2] lib: change how hbin sections are read.

Richard W.M. Jones rjones at redhat.com
Wed Feb 15 16:54:21 UTC 2017


On Tue, Feb 14, 2017 at 12:05:20PM -0500, Dawid Zamirski wrote:
> * hivex_open: when looping over hbin sections (aka pages), handle a
>   case where following hbin section may not begin at exactly at the end
>   of previous one. If this happens, scan the page section until next
>   one is found and validate it by checking declared offset with actual
>   one - if they match, all is good and we can safely move on.
> 
> Rationale: there are registry hives there is some garbage data between
> hbin section but the hive is still perfectly usable as long as the
> offsets stated in hbin headers are correct.
> ---
>  lib/handle.c | 39 ++++++++++++++++++++++++++++++++++-----
>  1 file changed, 34 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/handle.c b/lib/handle.c
> index 4565d7d..e183ff2 100644
> --- a/lib/handle.c
> +++ b/lib/handle.c
> @@ -226,11 +226,30 @@ hivex_open (const char *filename, int flags)
>          page->magic[1] != 'b' ||
>          page->magic[2] != 'i' ||
>          page->magic[3] != 'n') {
> -      SET_ERRNO (ENOTSUP,
> -                 "%s: trailing garbage at end of file "
> -                 "(at 0x%zx, after %zu pages)",
> -                 filename, off, pages);
> -      goto error;
> +
> +      DEBUG (2,
> +             "page not found at expected offset 0x%zx, "
> +             "seeking until one is found or EOF is reached",
> +             off);
> +
> +      int found = 0;
> +      while (off < h->endpages) {

GCC 7 warns:

handle.c: In function 'hivex_open':
handle.c:236:13: error: missed loop optimization, the loop counter may overflow [-Werror=unsafe-loop-optimizations]
       while (off < h->endpages) {
             ^

I suspect this means that GCC might try to turn this into an infinite
loop.

There are actually a few more of these in the existing code - I'm
going to push a patch to fix these in a minute.

Rich.

> +        off += 0x1000;
> +        page = (struct ntreg_hbin_page *) ((char *) h->addr + off);
> +        if (page->magic[0] == 'h' &&
> +            page->magic[1] == 'b' &&
> +            page->magic[2] == 'i' &&
> +            page->magic[3] == 'n') {
> +          DEBUG (2, "found next page by seeking at 0x%zx", off);
> +          found = 1;
> +          break;
> +        }
> +      }
> +
> +      if (!found) {
> +        DEBUG (2, "page not found and end of pages section reached");
> +        break;
> +      }
>      }
>  
>      size_t page_size = le32toh (page->page_size);
> @@ -254,6 +273,16 @@ hivex_open (const char *filename, int flags)
>        goto error;
>      }
>  
> +    size_t page_offset = le32toh(page->offset_first) + 0x1000;
> +
> +    if (page_offset != off) {
> +      SET_ERRNO (ENOTSUP,
> +                 "%s: declared page offset (0x%zx) does not match computed "
> +                 "offset (0x%zx), bad registry",
> +                 filename, page_offset, off);
> +      goto error;
> +    }
> +
>      /* Read the blocks in this page. */
>      size_t blkoff;
>      struct ntreg_hbin_block *block;
> -- 
> 2.9.3
> 
> _______________________________________________
> Libguestfs mailing list
> Libguestfs at redhat.com
> https://www.redhat.com/mailman/listinfo/libguestfs

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-p2v converts physical machines to virtual machines.  Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v




More information about the Libguestfs mailing list