Message ID | 20241002235253.487251-4-stephen.s.brennan@oracle.com (mailing list archive) |
---|---|
State | Not Applicable |
Delegated to: | BPF |
Headers | show |
Series | [dwarves,v3,1/5] btf_encoder: use bitfield to control var encoding | expand |
Context | Check | Description |
---|---|---|
netdev/tree_selection | success | Not a local patch |
On 03/10/2024 00:52, Stephen Brennan wrote: > The addr is a uint64_t, and depending on the size of a data section, > there's no guarantee that it fits into a uint32_t, even after > subtracting out the section start address. Similarly, the variable size > is a size_t which could exceed a uint32_t. Check both for overflow, and > if found, skip the variable with an error message. Use explicit casts > when we cast to uint32_t so it's plain to see that this is happening. > > Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com> Reviewed-by: Alan Maguire <alan.maguire@oracle.com> > --- > btf_encoder.c | 13 ++++++++++--- > 1 file changed, 10 insertions(+), 3 deletions(-) > > diff --git a/btf_encoder.c b/btf_encoder.c > index 31a418a..1872e00 100644 > --- a/btf_encoder.c > +++ b/btf_encoder.c > @@ -2250,9 +2250,16 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder) > > tag = cu__type(cu, var->ip.tag.type); > size = tag__size(tag, cu); > - if (size == 0) { > + if (size == 0 || size > UINT32_MAX) { > if (encoder->verbose) > - fprintf(stderr, "Ignoring zero-sized per-CPU variable '%s'...\n", name); > + fprintf(stderr, "Ignoring %s-sized per-CPU variable '%s'...\n", > + size == 0 ? "zero" : "over", name); > + continue; > + } > + if (addr > UINT32_MAX) { > + if (encoder->verbose) > + fprintf(stderr, "Ignoring variable '%s' - its offset %zu doesn't fit in a u32\n", > + name, addr); > continue; > } > > @@ -2285,7 +2292,7 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder) > * add a BTF_VAR_SECINFO in encoder->percpu_secinfo, which will be added into > * encoder->types later when we add BTF_VAR_DATASEC. > */ > - id = btf_encoder__add_var_secinfo(encoder, id, addr, size); > + id = btf_encoder__add_var_secinfo(encoder, id, (uint32_t)addr, (uint32_t)size); > if (id < 0) { > fprintf(stderr, "error: failed to encode section info for variable '%s' at addr 0x%" PRIx64 "\n", > name, addr);
diff --git a/btf_encoder.c b/btf_encoder.c index 31a418a..1872e00 100644 --- a/btf_encoder.c +++ b/btf_encoder.c @@ -2250,9 +2250,16 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder) tag = cu__type(cu, var->ip.tag.type); size = tag__size(tag, cu); - if (size == 0) { + if (size == 0 || size > UINT32_MAX) { if (encoder->verbose) - fprintf(stderr, "Ignoring zero-sized per-CPU variable '%s'...\n", name); + fprintf(stderr, "Ignoring %s-sized per-CPU variable '%s'...\n", + size == 0 ? "zero" : "over", name); + continue; + } + if (addr > UINT32_MAX) { + if (encoder->verbose) + fprintf(stderr, "Ignoring variable '%s' - its offset %zu doesn't fit in a u32\n", + name, addr); continue; } @@ -2285,7 +2292,7 @@ static int btf_encoder__encode_cu_variables(struct btf_encoder *encoder) * add a BTF_VAR_SECINFO in encoder->percpu_secinfo, which will be added into * encoder->types later when we add BTF_VAR_DATASEC. */ - id = btf_encoder__add_var_secinfo(encoder, id, addr, size); + id = btf_encoder__add_var_secinfo(encoder, id, (uint32_t)addr, (uint32_t)size); if (id < 0) { fprintf(stderr, "error: failed to encode section info for variable '%s' at addr 0x%" PRIx64 "\n", name, addr);
The addr is a uint64_t, and depending on the size of a data section, there's no guarantee that it fits into a uint32_t, even after subtracting out the section start address. Similarly, the variable size is a size_t which could exceed a uint32_t. Check both for overflow, and if found, skip the variable with an error message. Use explicit casts when we cast to uint32_t so it's plain to see that this is happening. Signed-off-by: Stephen Brennan <stephen.s.brennan@oracle.com> --- btf_encoder.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-)