summaryrefslogtreecommitdiffstats
path: root/libdwfl
diff options
context:
space:
mode:
authorMark Wielaard <mark@klomp.org>2021-12-08 13:39:47 +0100
committerMark Wielaard <mark@klomp.org>2021-12-09 19:34:19 +0100
commit809f2d70ec770d512cf6b1e70a67f5eb84c4508c (patch)
tree1a745ee9b16367578b8fc2dc25b573956dbb8639 /libdwfl
parentdebuginfod: Don't format clog using 'right' or 'setw(20)'. (diff)
downloadelfutils-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/ChangeLog6
-rw-r--r--libdwfl/link_map.c17
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 @@
12021-12-08 Mark Wielaard <mark@klomp.org> 12021-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
72021-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))