* [PATCH dwarves] dwarf_loader: Fix heap overflow when accessing variable specification
@ 2021-10-12 2:25 Ilya Leoshkevich
2021-10-15 12:53 ` Arnaldo Carvalho de Melo
0 siblings, 1 reply; 2+ messages in thread
From: Ilya Leoshkevich @ 2021-10-12 2:25 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo
Cc: dwarves, bpf, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Heiko Carstens, Vasily Gorbik, Ilya Leoshkevich
Variables can be allocated with or without specification, however,
tag__recode_dwarf_type() always tries accessing it, leading to heap
read overflows and subsequent logic bugs.
Fix by introducing a bit that tracks whether or not specification is
present.
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
dwarf_loader.c | 15 ++++++++++-----
dwarves.h | 1 +
2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/dwarf_loader.c b/dwarf_loader.c
index 48e1bf0..60bdca3 100644
--- a/dwarf_loader.c
+++ b/dwarf_loader.c
@@ -723,6 +723,7 @@ static struct variable *variable__new(Dwarf_Die *die, struct cu *cu, struct conf
var->external = dwarf_hasattr(die, DW_AT_external);
/* non-defining declaration of an object */
var->declaration = dwarf_hasattr(die, DW_AT_declaration);
+ var->has_specification = has_specification;
var->scope = VSCOPE_UNKNOWN;
INIT_LIST_HEAD(&var->annots);
var->ip.addr = 0;
@@ -2291,12 +2292,16 @@ static int tag__recode_dwarf_type(struct tag *tag, struct cu *cu)
goto find_type;
case DW_TAG_variable: {
struct variable *var = tag__variable(tag);
- dwarf_off_ref specification = dwarf_tag__spec(dtag);
- if (specification.off) {
- dtype = dwarf_cu__find_tag_by_ref(cu->priv, &specification);
- if (dtype)
- var->spec = tag__variable(dtype->tag);
+ if (var->has_specification) {
+ dwarf_off_ref specification = dwarf_tag__spec(dtag);
+
+ if (specification.off) {
+ dtype = dwarf_cu__find_tag_by_ref(cu->priv,
+ &specification);
+ if (dtype)
+ var->spec = tag__variable(dtype->tag);
+ }
}
}
diff --git a/dwarves.h b/dwarves.h
index 30d33fa..20608dd 100644
--- a/dwarves.h
+++ b/dwarves.h
@@ -691,6 +691,7 @@ struct variable {
const char *name;
uint8_t external:1;
uint8_t declaration:1;
+ uint8_t has_specification:1;
enum vscope scope;
struct location location;
struct hlist_node tool_hnode;
--
2.31.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH dwarves] dwarf_loader: Fix heap overflow when accessing variable specification
2021-10-12 2:25 [PATCH dwarves] dwarf_loader: Fix heap overflow when accessing variable specification Ilya Leoshkevich
@ 2021-10-15 12:53 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 2+ messages in thread
From: Arnaldo Carvalho de Melo @ 2021-10-15 12:53 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Arnaldo Carvalho de Melo, dwarves, bpf, Alexei Starovoitov,
Daniel Borkmann, Andrii Nakryiko, Heiko Carstens, Vasily Gorbik
Em Tue, Oct 12, 2021 at 04:25:21AM +0200, Ilya Leoshkevich escreveu:
> Variables can be allocated with or without specification, however,
> tag__recode_dwarf_type() always tries accessing it, leading to heap
> read overflows and subsequent logic bugs.
>
> Fix by introducing a bit that tracks whether or not specification is
> present.
Thanks, applied.
- Arnaldo
> Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
> ---
> dwarf_loader.c | 15 ++++++++++-----
> dwarves.h | 1 +
> 2 files changed, 11 insertions(+), 5 deletions(-)
>
> diff --git a/dwarf_loader.c b/dwarf_loader.c
> index 48e1bf0..60bdca3 100644
> --- a/dwarf_loader.c
> +++ b/dwarf_loader.c
> @@ -723,6 +723,7 @@ static struct variable *variable__new(Dwarf_Die *die, struct cu *cu, struct conf
> var->external = dwarf_hasattr(die, DW_AT_external);
> /* non-defining declaration of an object */
> var->declaration = dwarf_hasattr(die, DW_AT_declaration);
> + var->has_specification = has_specification;
> var->scope = VSCOPE_UNKNOWN;
> INIT_LIST_HEAD(&var->annots);
> var->ip.addr = 0;
> @@ -2291,12 +2292,16 @@ static int tag__recode_dwarf_type(struct tag *tag, struct cu *cu)
> goto find_type;
> case DW_TAG_variable: {
> struct variable *var = tag__variable(tag);
> - dwarf_off_ref specification = dwarf_tag__spec(dtag);
>
> - if (specification.off) {
> - dtype = dwarf_cu__find_tag_by_ref(cu->priv, &specification);
> - if (dtype)
> - var->spec = tag__variable(dtype->tag);
> + if (var->has_specification) {
> + dwarf_off_ref specification = dwarf_tag__spec(dtag);
> +
> + if (specification.off) {
> + dtype = dwarf_cu__find_tag_by_ref(cu->priv,
> + &specification);
> + if (dtype)
> + var->spec = tag__variable(dtype->tag);
> + }
> }
> }
>
> diff --git a/dwarves.h b/dwarves.h
> index 30d33fa..20608dd 100644
> --- a/dwarves.h
> +++ b/dwarves.h
> @@ -691,6 +691,7 @@ struct variable {
> const char *name;
> uint8_t external:1;
> uint8_t declaration:1;
> + uint8_t has_specification:1;
> enum vscope scope;
> struct location location;
> struct hlist_node tool_hnode;
> --
> 2.31.1
--
- Arnaldo
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2021-10-15 12:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-12 2:25 [PATCH dwarves] dwarf_loader: Fix heap overflow when accessing variable specification Ilya Leoshkevich
2021-10-15 12:53 ` Arnaldo Carvalho de Melo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).