summaryrefslogtreecommitdiffstats
path: root/libelf/gelf_getnote.c
diff options
context:
space:
mode:
authorMark Wielaard <[email protected]>2019-01-11 13:39:27 +0100
committerMark Wielaard <[email protected]>2019-01-11 13:39:27 +0100
commitb244a241a82c28f7fef33f37d82bc47631ceca4e (patch)
tree8b83c72f0a99dca6624f0903e8c3ee1eb26ad900 /libelf/gelf_getnote.c
parent029c76f0d4b06584e370b5fc0112712ba99a6219 (diff)
parent4ea9a2db164caadf836a65d5cdffb09a2d5a37ce (diff)
Merge tag 'elfutils-0.175' into mjw/RH-DTSdts-0.175
elfutils 0.175 release
Diffstat (limited to 'libelf/gelf_getnote.c')
-rw-r--r--libelf/gelf_getnote.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/libelf/gelf_getnote.c b/libelf/gelf_getnote.c
index c75eddab..6d33b355 100644
--- a/libelf/gelf_getnote.c
+++ b/libelf/gelf_getnote.c
@@ -1,5 +1,5 @@
/* Get note information at the supplied offset.
- Copyright (C) 2007, 2014, 2015 Red Hat, Inc.
+ Copyright (C) 2007, 2014, 2015, 2018 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -43,7 +43,7 @@ gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result,
if (data == NULL)
return 0;
- if (unlikely (data->d_type != ELF_T_NHDR))
+ if (unlikely (data->d_type != ELF_T_NHDR && data->d_type != ELF_T_NHDR8))
{
__libelf_seterrno (ELF_E_INVALID_HANDLE);
return 0;
@@ -69,27 +69,42 @@ gelf_getnote (Elf_Data *data, size_t offset, GElf_Nhdr *result,
const GElf_Nhdr *n = data->d_buf + offset;
offset += sizeof *n;
- /* Include padding. Check below for overflow. */
- GElf_Word namesz = NOTE_ALIGN (n->n_namesz);
- GElf_Word descsz = NOTE_ALIGN (n->n_descsz);
-
- if (unlikely (offset > data->d_size
- || data->d_size - offset < namesz
- || (namesz == 0 && n->n_namesz != 0)))
+ if (offset > data->d_size)
offset = 0;
else
{
+ /* This is slightly tricky, offset is guaranteed to be 4
+ byte aligned, which is what we need for the name_offset.
+ And normally desc_offset is also 4 byte aligned, but not
+ for GNU Property notes, then it should be 8. So align
+ the offset, after adding the namesz, and include padding
+ in descsz to get to the end. */
*name_offset = offset;
- offset += namesz;
- if (unlikely (offset > data->d_size
- || data->d_size - offset < descsz
- || (descsz == 0 && n->n_descsz != 0)))
+ offset += n->n_namesz;
+ if (offset > data->d_size)
offset = 0;
else
{
- *desc_offset = offset;
- offset += descsz;
- *result = *n;
+ /* Include padding. Check below for overflow. */
+ GElf_Word descsz = (data->d_type == ELF_T_NHDR8
+ ? NOTE_ALIGN8 (n->n_descsz)
+ : NOTE_ALIGN4 (n->n_descsz));
+
+ if (data->d_type == ELF_T_NHDR8)
+ offset = NOTE_ALIGN8 (offset);
+ else
+ offset = NOTE_ALIGN4 (offset);
+
+ if (unlikely (offset > data->d_size
+ || data->d_size - offset < descsz
+ || (descsz == 0 && n->n_descsz != 0)))
+ offset = 0;
+ else
+ {
+ *desc_offset = offset;
+ offset += descsz;
+ *result = *n;
+ }
}
}
}