diff options
author | Alex Arslan <ararslan@comcast.net> | 2021-11-05 16:58:41 -0700 |
---|---|---|
committer | Dave Watson <dade.watson@gmail.com> | 2021-11-26 08:58:15 -0800 |
commit | 8b3832fea8a343ec0888545088c859074aaee20f (patch) | |
tree | 8ec26fb0c54aba55173627494eb83f55bccc676c /src/dwarf | |
parent | b9ac0802cd0a7fa5c2d7ee4e20b3626bb7ef12fe (diff) | |
download | libunwind-8b3832fea8a343ec0888545088c859074aaee20f.tar.gz |
Fix table indexing in `dwarf_search_unwind_table`
`table_len` is used as an index into `table`, assuming it represents the
number of entries. However, it is defined as the number of entries
multiplied by `sizeof(unw_word_t)`. This is accounted for in other
places that use `table_len`, e.g. in `lookup`, which divides out the
size of `unw_word_t`, but the indexing expression uses `table_len`
directly. So when `table` has say 2 entries, we're actually looking at
index 16 rather than 2 in the comparison. This can cause the conditional
to erroneously evaluate to true, allowing the following line to
segfault.
This was observed with JIT compiled code from Julia with LLVM on
FreeBSD.
Co-Authored-By: Jameson Nash <vtjnash@gmail.com>
Diffstat (limited to 'src/dwarf')
-rw-r--r-- | src/dwarf/Gfind_proc_info-lsb.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/src/dwarf/Gfind_proc_info-lsb.c b/src/dwarf/Gfind_proc_info-lsb.c index 7f170915..35bb2df0 100644 --- a/src/dwarf/Gfind_proc_info-lsb.c +++ b/src/dwarf/Gfind_proc_info-lsb.c @@ -966,7 +966,7 @@ dwarf_search_unwind_table (unw_addr_space_t as, unw_word_t ip, if (as == unw_local_addr_space) { e = lookup (table, table_len, ip - ip_base - di->load_offset); - if (e && &e[1] < &table[table_len]) + if (e && &e[1] < &table[table_len / sizeof (unw_word_t)]) last_ip = e[1].start_ip_offset + ip_base + di->load_offset; else last_ip = di->end_ip; |