diff options
author | Mark Wielaard <mark@klomp.org> | 2021-12-08 13:39:47 +0100 |
---|---|---|
committer | Mark Wielaard <mark@klomp.org> | 2021-12-09 19:34:19 +0100 |
commit | 809f2d70ec770d512cf6b1e70a67f5eb84c4508c (patch) | |
tree | 1a745ee9b16367578b8fc2dc25b573956dbb8639 /libdwfl | |
parent | debuginfod: Don't format clog using 'right' or 'setw(20)'. (diff) | |
download | elfutils-809f2d70ec770d512cf6b1e70a67f5eb84c4508c.tar.gz elfutils-809f2d70ec770d512cf6b1e70a67f5eb84c4508c.tar.bz2 elfutils-809f2d70ec770d512cf6b1e70a67f5eb84c4508c.tar.xz |
libdwfl: Don't try to convert too many bytes in dwfl_link_map_report
When trying to read (corrupt) phdrs from a core file we only want
to read and convert the bytes we could read. Also make sure we don't
try to allocate too big buffers.
https://sourceware.org/bugzilla/show_bug.cgi?id=28666
Signed-off-by: Mark Wielaard <mark@klomp.org>
Diffstat (limited to 'libdwfl')
-rw-r--r-- | libdwfl/ChangeLog | 6 | ||||
-rw-r--r-- | libdwfl/link_map.c | 17 |
2 files changed, 21 insertions, 2 deletions
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog index b2a8752a..96251f0d 100644 --- a/libdwfl/ChangeLog +++ b/libdwfl/ChangeLog | |||
@@ -1,5 +1,11 @@ | |||
1 | 2021-12-08 Mark Wielaard <mark@klomp.org> | 1 | 2021-12-08 Mark Wielaard <mark@klomp.org> |
2 | 2 | ||
3 | * link_map.c (dwfl_link_map_report): Limit malloc size to max | ||
4 | possible. When converting make sure we don't exceed the number | ||
5 | of bytes available in either in.d_buf nor out.d_buf. | ||
6 | |||
7 | 2021-12-08 Mark Wielaard <mark@klomp.org> | ||
8 | |||
3 | * dwfl_segment_report_module.c (dwfl_segment_report_module): Don't | 9 | * dwfl_segment_report_module.c (dwfl_segment_report_module): Don't |
4 | read beyond of (actual) end of (memory) file. | 10 | read beyond of (actual) end of (memory) file. |
5 | 11 | ||
diff --git a/libdwfl/link_map.c b/libdwfl/link_map.c index 1e7d4502..1c298a8e 100644 --- a/libdwfl/link_map.c +++ b/libdwfl/link_map.c | |||
@@ -847,6 +847,11 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, | |||
847 | /* Note this in the !in_ok path. That means memory_callback | 847 | /* Note this in the !in_ok path. That means memory_callback |
848 | failed. But the callback might still have reset the d_size | 848 | failed. But the callback might still have reset the d_size |
849 | value (to zero). So explicitly set it here again. */ | 849 | value (to zero). So explicitly set it here again. */ |
850 | if (unlikely (phnum > SIZE_MAX / phent)) | ||
851 | { | ||
852 | __libdwfl_seterrno (DWFL_E_NOMEM); | ||
853 | return false; | ||
854 | } | ||
850 | in.d_size = phnum * phent; | 855 | in.d_size = phnum * phent; |
851 | in.d_buf = malloc (in.d_size); | 856 | in.d_buf = malloc (in.d_size); |
852 | if (unlikely (in.d_buf == NULL)) | 857 | if (unlikely (in.d_buf == NULL)) |
@@ -876,6 +881,13 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, | |||
876 | return false; | 881 | return false; |
877 | } | 882 | } |
878 | size_t nbytes = phnum * phent; | 883 | size_t nbytes = phnum * phent; |
884 | /* We can only process as many bytes/phnum as there are | ||
885 | in in.d_size. The data might have been truncated. */ | ||
886 | if (nbytes > in.d_size) | ||
887 | { | ||
888 | nbytes = in.d_size; | ||
889 | phnum = nbytes / phent; | ||
890 | } | ||
879 | void *buf = malloc (nbytes); | 891 | void *buf = malloc (nbytes); |
880 | Elf32_Phdr (*p32)[phnum] = buf; | 892 | Elf32_Phdr (*p32)[phnum] = buf; |
881 | Elf64_Phdr (*p64)[phnum] = buf; | 893 | Elf64_Phdr (*p64)[phnum] = buf; |
@@ -888,10 +900,11 @@ dwfl_link_map_report (Dwfl *dwfl, const void *auxv, size_t auxv_size, | |||
888 | { | 900 | { |
889 | .d_type = ELF_T_PHDR, | 901 | .d_type = ELF_T_PHDR, |
890 | .d_version = EV_CURRENT, | 902 | .d_version = EV_CURRENT, |
891 | .d_size = phnum * phent, | 903 | .d_size = nbytes, |
892 | .d_buf = buf | 904 | .d_buf = buf |
893 | }; | 905 | }; |
894 | in.d_size = out.d_size; | 906 | if (in.d_size > out.d_size) |
907 | in.d_size = out.d_size; | ||
895 | if (likely ((elfclass == ELFCLASS32 | 908 | if (likely ((elfclass == ELFCLASS32 |
896 | ? elf32_xlatetom : elf64_xlatetom) | 909 | ? elf32_xlatetom : elf64_xlatetom) |
897 | (&out, &in, elfdata) != NULL)) | 910 | (&out, &in, elfdata) != NULL)) |