Fix handling of nvlist array
This commit is contained in:
parent
069142f4c2
commit
e5c63d9d41
2 changed files with 32 additions and 18 deletions
|
@ -1812,13 +1812,28 @@ grub_zfs_nvlist_lookup_nvlist_array_get_nelm (char *nvlist, char *name)
|
||||||
grub_size_t nelm, size;
|
grub_size_t nelm, size;
|
||||||
int found;
|
int found;
|
||||||
|
|
||||||
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
|
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair,
|
||||||
&size, &nelm);
|
&size, &nelm);
|
||||||
if (! found)
|
if (! found)
|
||||||
return -1;
|
return -1;
|
||||||
return nelm;
|
return nelm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
get_nvlist_size (char *beg, char *limit)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
grub_uint32_t encode_size;
|
||||||
|
|
||||||
|
ptr = beg + 8;
|
||||||
|
|
||||||
|
while (ptr < limit
|
||||||
|
&& (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) ptr)))
|
||||||
|
ptr += encode_size; /* goto the next nvpair */
|
||||||
|
ptr += 8;
|
||||||
|
return (ptr > limit) ? -1 : (ptr - beg);
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name,
|
grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name,
|
||||||
grub_size_t index)
|
grub_size_t index)
|
||||||
|
@ -1829,8 +1844,9 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name,
|
||||||
grub_size_t size;
|
grub_size_t size;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
grub_size_t nelm;
|
grub_size_t nelm;
|
||||||
|
int elemsize = 0;
|
||||||
|
|
||||||
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST, &nvpair,
|
found = nvlist_find_value (nvlist, name, DATA_TYPE_NVLIST_ARRAY, &nvpair,
|
||||||
&size, &nelm);
|
&size, &nelm);
|
||||||
if (!found)
|
if (!found)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -1844,33 +1860,31 @@ grub_zfs_nvlist_lookup_nvlist_array (char *nvlist, char *name,
|
||||||
|
|
||||||
for (i = 0; i < index; i++)
|
for (i = 0; i < index; i++)
|
||||||
{
|
{
|
||||||
grub_uint32_t encode_size;
|
int r;
|
||||||
|
r = get_nvlist_size (nvpairptr, nvpair + size);
|
||||||
|
|
||||||
/* skip the header, nvl_version, and nvl_nvflag */
|
if (r < 0)
|
||||||
nvpairptr = nvpairptr + 4 * 2;
|
{
|
||||||
|
grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array");
|
||||||
while (nvpairptr < nvpair + size
|
return NULL;
|
||||||
&& (encode_size = grub_be_to_cpu32 (*(grub_uint32_t *) nvpairptr)))
|
}
|
||||||
nvlist += encode_size; /* goto the next nvpair */
|
nvpairptr += r;
|
||||||
|
|
||||||
nvlist = nvlist + 4 * 2; /* skip the ending 2 zeros - 8 bytes */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nvpairptr >= nvpair + size
|
elemsize = get_nvlist_size (nvpairptr, nvpair + size);
|
||||||
|| nvpairptr + grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2))
|
|
||||||
>= nvpair + size)
|
if (elemsize < 0)
|
||||||
{
|
{
|
||||||
grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array");
|
grub_error (GRUB_ERR_BAD_FS, "incorrect nvlist array");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = grub_zalloc (grub_be_to_cpu32 (*(grub_uint32_t *) (nvpairptr + 4 * 2))
|
ret = grub_zalloc (elemsize + sizeof (grub_uint32_t));
|
||||||
+ 3 * sizeof (grub_uint32_t));
|
|
||||||
if (!ret)
|
if (!ret)
|
||||||
return 0;
|
return 0;
|
||||||
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
grub_memcpy (ret, nvlist, sizeof (grub_uint32_t));
|
||||||
|
|
||||||
grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, size);
|
grub_memcpy (ret + sizeof (grub_uint32_t), nvpairptr, elemsize);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -139,7 +139,6 @@ print_vdev_info (char *nvlist, int tab)
|
||||||
}
|
}
|
||||||
grub_printf ("Mirror VDEV with %d children\n", nelm);
|
grub_printf ("Mirror VDEV with %d children\n", nelm);
|
||||||
print_state (nvlist, tab);
|
print_state (nvlist, tab);
|
||||||
|
|
||||||
for (i = 0; i < nelm; i++)
|
for (i = 0; i < nelm; i++)
|
||||||
{
|
{
|
||||||
char *child;
|
char *child;
|
||||||
|
@ -159,6 +158,7 @@ print_vdev_info (char *nvlist, int tab)
|
||||||
|
|
||||||
grub_free (child);
|
grub_free (child);
|
||||||
}
|
}
|
||||||
|
return GRUB_ERR_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
print_tabs (tab);
|
print_tabs (tab);
|
||||||
|
|
Loading…
Reference in a new issue