Bug 23248 - armv7l: dwarf_getsrclines.c:362:37: error: argument 1 value '4294967288' exceeds maximum object size 2147483647 [-Werror=alloc-size-larger-than=]
Summary: armv7l: dwarf_getsrclines.c:362:37: error: argument 1 value '4294967288' exce...
Status: RESOLVED FIXED
Alias: None
Product: elfutils
Classification: Unclassified
Component: tools (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-05-30 10:16 UTC by Martin Liska
Modified: 2018-05-31 19:49 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Martin Liska 2018-05-30 10:16:20 UTC
I see it in build service for 0.171 RC1:

[  181s] dwarf_getsrclines.c: In function 'read_srclines':
[  181s] dwarf_getsrclines.c:362:37: error: argument 1 value '4294967288' exceeds maximum object size 2147483647 [-Werror=alloc-size-larger-than=]
[  181s]        dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray));
[  181s]                                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[  181s] In file included from dwarf_getsrclines.c:34:
[  181s] /usr/include/stdlib.h:539:14: note: in a call to allocation function 'malloc' declared here
[  181s]  extern void *malloc (size_t __size) __THROW __attribute_malloc__ __wur;
[  181s]               ^~~~~~

Unfortunately I don't have any handy ARM machine I can reproduce that. But probably caused by:

libdw/memory-access.h:
    73  static inline uint64_t
    74  __libdw_get_uleb128 (const unsigned char **addrp, const unsigned char *end)
    75  {
    76    uint64_t acc = 0;
    77  
    78    /* Unroll the first step to help the compiler optimize
    79       for the common single-byte case.  */
    80    get_uleb128_step (acc, *addrp, 0);
    81  
    82    const size_t max = __libdw_max_len_uleb128 (*addrp - 1, end);
    83    for (size_t i = 1; i < max; ++i)
    84      get_uleb128_step (acc, *addrp, i);
    85    /* Other implementations set VALUE to UINT_MAX in this
    86       case.  So we better do this as well.  */
    87    return UINT64_MAX;
    88  }
Comment 1 Martin Liska 2018-05-30 11:06:12 UTC
The same happens on i586, after lunch I'll isolate that.
Comment 2 Mark Wielaard 2018-05-30 12:23:37 UTC
ndirs is read from the debug data and should be size checked before use.
Does the following work for you?

diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index 2bf30984..c353e5b7 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -359,6 +359,8 @@ read_srclines (Dwarf *dbg,
   ndirlist = ndirs;
   if (ndirlist >= MAX_STACK_DIRS)
     {
+      if (ndirlist > SIZE_MAX / sizeof (*dirarray))
+       goto no_mem;
       dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray));
       if (unlikely (dirarray == NULL))
        {
Comment 3 Mark Wielaard 2018-05-30 12:49:58 UTC
Martin pointed out that only works (on 64bit) if ndirlist was actually a size_t (like nfilelist already is). So the full patch would be:

diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index 2bf30984..790d4e49 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -154,7 +154,7 @@ read_srclines (Dwarf *dbg,
   int res = -1;
 
   size_t nfilelist = 0;
-  unsigned int ndirlist = 0;
+  size_t ndirlist = 0;
 
   /* If there are a large number of lines, files or dirs don't blow up
      the stack.  Stack allocate some entries, only dynamically malloc
@@ -299,7 +299,7 @@ read_srclines (Dwarf *dbg,
   };
 
   /* First count the entries.  */
-  unsigned int ndirs = 0;
+  size_t ndirs = 0;
   if (version < 5)
     {
       const unsigned char *dirp = linep;
@@ -359,6 +359,8 @@ read_srclines (Dwarf *dbg,
   ndirlist = ndirs;
   if (ndirlist >= MAX_STACK_DIRS)
     {
+      if (ndirlist > SIZE_MAX / sizeof (*dirarray))
+       goto no_mem;
       dirarray = (struct dirlist *) malloc (ndirlist * sizeof (*dirarray));
       if (unlikely (dirarray == NULL))
        {
Comment 4 Mark Wielaard 2018-05-31 19:49:52 UTC
commit 3a5bbc919873fc8adee7345dd7dec585eb4d2547 (wildebeest/buildbot, origin/master, origin/HEAD, master, buildbot)
Author: Mark Wielaard <mark@klomp.org>
Date:   Wed May 30 15:51:12 2018 +0200

    libdw: Fix overflow warning on 32bit systems with GCC8 in dwarf_getsrclines.
    
    ndirs is read from the debug data and should be size checked before use.
    
    https://sourceware.org/bugzilla/show_bug.cgi?id=23248
    
    Signed-off-by: Mark Wielaard <mark@klomp.org>