Bug 88890 - libbacktrace on 32-bit system with _FILE_OFFSET_BITS == 64
Summary: libbacktrace on 32-bit system with _FILE_OFFSET_BITS == 64
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libbacktrace (show other bugs)
Version: 9.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-01-17 12:40 UTC by Tom de Vries
Modified: 2019-01-18 17:29 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom de Vries 2019-01-17 12:40:35 UTC
In libbacktrace we use views to load portions of files into memory:
...
extern int backtrace_get_view (struct backtrace_state *state, int descriptor,
                               off_t offset, size_t size,
                               backtrace_error_callback error_callback,
                               void *data, struct backtrace_view *view);
...

One example using this function is:
...
  off_t min_offset;
  off_t max_offset;

  ...

  /* Read all the debug sections in a single view, since they are                                                 
     probably adjacent in the file.  We never release this view.  */

  min_offset = 0;
  max_offset = 0;
  for (i = 0; i < (int) DEBUG_MAX; ++i)
    {
      off_t end;

      if (sections[i].size == 0)
        continue;
      if (min_offset == 0 || sections[i].offset < min_offset)
        min_offset = sections[i].offset;
      end = sections[i].offset + sections[i].size;
      if (end > max_offset)
        max_offset = end;
    }
  if (min_offset == 0 || max_offset == 0)
    {
      if (!backtrace_close (descriptor, error_callback, data))
        goto fail;
      return 1;
    }

  if (!backtrace_get_view (state, descriptor, min_offset,
                           max_offset - min_offset,
                           error_callback, data, &debug_view))
    goto fail;
  debug_view_valid = 1;
...

In the case of a 32-bit system with _FILE_OFFSET_BITS == 64, well have size_t 32-bit unsigned and off_t 64-bit signed, so the max_offset - min_offset argument for the size parameter may be bigger than the size_t type of the size parameter allows.

ISTM that the easiest way to fix this, is to change the type of the size parameter to off_t, and to figure out in the implementation of backtrace_get_view whether the value of size fits in size_t, and if not, return with failure.
Comment 1 ian@gcc.gnu.org 2019-01-18 17:14:34 UTC
Author: ian
Date: Fri Jan 18 17:13:59 2019
New Revision: 268082

URL: https://gcc.gnu.org/viewcvs?rev=268082&root=gcc&view=rev
Log:
	PR libbacktrace/88890
	* mmapio.c (backtrace_get_view): Change size parameter to
	uint64_t.  Check that value fits in size_t.
	* read.c (backtrace_get_view): Likewise.
	* internal.h (backtrace_get_view): Update declaration.
	* elf.c (elf_add): Pass shstrhdr->sh_size to backtrace_get_view.

Modified:
    trunk/libbacktrace/ChangeLog
    trunk/libbacktrace/elf.c
    trunk/libbacktrace/internal.h
    trunk/libbacktrace/mmapio.c
    trunk/libbacktrace/read.c
Comment 2 Ian Lance Taylor 2019-01-18 17:29:26 UTC
Fixed.