public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Joel Brobecker <brobecker@adacore.com>
To: Simon Marchi <simark@simark.ca>
Cc: gdb-patches@sourceware.org
Subject: Re: [RFA 2/2] gmp-utils: protect gdb_mpz exports against out-of-range values
Date: Tue, 1 Dec 2020 07:37:25 +0400	[thread overview]
Message-ID: <20201201033725.GA3501@adacore.com> (raw)
In-Reply-To: <ff6e02e4-57fd-095f-ca84-241b142e20e3@simark.ca>

Hi Simon,

Thanks for the review! My preliminary answers below..

> > +void
> > +gdb_mpz::safe_export (gdb::array_view<gdb_byte> buf,
> > +		      int endian, size_t nails, bool unsigned_p) const
> 
> Just wondering if you'll ever need to pass a non-zero value for nails.
> If not, I think you could simplify the code by just removing it.

I don't know for sure. What about a scenario where we want to export
to a variable which is held in an area that's not a multiple number
of bytes?

The code isn't dramatically complexified because of it, so perhaps
just keep it by default, and remove it later, if we find that
we never used it?

> > +{
> > +  gdb_assert (buf.size () > 0);
> > +
> > +  if (mpz_sgn (val) == 0)
> > +    {
> > +      /* Our value is zero, so no need to call mpz_export to do the work,
> > +	 especially since mpz_export's documentation explicitly says
> > +	 that the function is a noop in this case.  Just write zero to
> > +	 BUF ourselves.  */
> > +      memset (buf.data (), 0, buf.size ());
> > +      return;
> > +    }
> > +
> > +  /* Determine the maximum range of values that our buffer can hold,
> > +     and verify that VAL is within that range.  */
> > +
> > +  gdb_mpz lo, hi;
> > +  const size_t max_usable_bits = buf.size () * HOST_CHAR_BIT - nails;
> > +  if (unsigned_p)
> > +    {
> > +      lo = 0;
> > +
> > +      mpz_ui_pow_ui (hi.val, 2, max_usable_bits);
> > +      mpz_sub_ui (hi.val, hi.val, 1);
> > +    }
> > +  else
> > +    {
> > +      mpz_ui_pow_ui (lo.val, 2, max_usable_bits - 1);
> > +      mpz_neg (lo.val, lo.val);
> > +
> > +      mpz_ui_pow_ui (hi.val, 2, max_usable_bits - 1);
> > +      mpz_sub_ui (hi.val, hi.val, 1);
> > +    }
> > +
> > +  if (mpz_cmp (val, lo.val) < 0 || mpz_cmp (val, hi.val) > 0)
> > +    error (_("Cannot export value %s as %zubits %s integer"
> > +	     " (must be between %s and %s)"),
> 
> You might be missing a space before "bits", or maybe it's on purpose.

It was on purpose, as I tend to write "32bit object" or "64bit object".
But if there is a standard way to write these things. A quick google
search indeed seems to indicate that there is large preference for
having a dash (as in "32-bit computing").

So, if people agree, I will change the above to add a dash.

> 
> > +	   this->str ().c_str (),
> > +	   max_usable_bits,
> > +	   unsigned_p ? _("unsigned") : _("signed"),
> > +	   lo.str ().c_str (),
> > +	   hi.str ().c_str ());
> > +
> >    gdb_mpz exported_val (val);
> >
> > -  if (mpz_cmp_ui (val, 0) < 0)
> > +  if (mpz_cmp_ui (exported_val.val, 0) < 0)
> >      {
> >        /* mpz_export does not handle signed values, so create a positive
> >  	 value whose bit representation as an unsigned of the same length
> > @@ -81,13 +134,27 @@ gdb_mpz::write (gdb::array_view<gdb_byte> buf, enum bfd_endian byte_order,
> >        mpz_add (exported_val.val, exported_val.val, neg_offset.val);
> >      }
> >
> > +  /* Do the export into a buffer allocated by GMP itself; that way,
> > +     we can detect cases where BUF is not large enough to export
> > +     our value, and thus avoid a buffer overlow.  Normally, this should
> > +     never happen, since we verified earlier that the buffer is large
> > +     enough to accomodate our value, but doing this allows us to be
> > +     extra safe with the export.
> > +
> > +     After verification that the export behaved as expected, we will
> > +     copy the data over to BUF.  */
> > +
> > +  size_t word_countp;
> > +  gdb::unique_xmalloc_ptr<void> exported
> 
> I'd prefer if we didn't use heap allocation unnecessarily.  If we get
> things right, that isn't necessary.  And if we can still assert after
> the call that we did indeed get it right, then we'll catch any case
> where we didn't.

The problem with what you suggest is that, if we didn't do things right,
by the time we realize it, we'll have already gone through a buffer
overflow, with the associated random and uncontrolled damage. On Ubuntu,
we already know that the overflow causes an abort, so we wouldn't even
get to the point where we'd double-check. For me, this risk is bad enough
that it's well worth this (small) extra allocation.  I don't think
this function is going to be called very frequently.

> > +    (mpz_export (NULL, &word_countp, -1 /* order */, buf.size () /* size */,
> > +		 endian, nails, exported_val.val));
> > +
> > +  gdb_assert (word_countp == 1);
> > +
> >    /* Start by clearing the buffer, as mpz_export only writes as many
> > -     bytes as it needs (including none, if the value to export is zero.  */
> > +     bytes as it needs.  */
> >    memset (buf.data (), 0, buf.size ());
> > -  mpz_export (buf.data (), NULL /* count */, -1 /* order */,
> > -	      buf.size () /* size */,
> > -	      byte_order == BFD_ENDIAN_BIG ? 1 : -1 /* endian */,
> > -	      0 /* nails */, exported_val.val);
> > +  memcpy (buf.data (), exported.get (), buf.size ());
> 
> The memset just before the memcpy of the same size is useless, as all
> the bytes will get overwritten by the memcpy.

Indeed. The above comes from my belief that mpz_export only writes
the necessary number of *bytes*, but re-reading the documentation,
I belive it's the necessary number of *words*. I don't know how things
could possibly be working in the case where mpz_export does the memory
allocation otherwise.

Thanks for catching that. I'll remove the extra memset.

> > @@ -258,26 +278,14 @@ template<typename T>
> >  T
> >  gdb_mpz::as_integer () const
> >  {
> > -  /* Initialize RESULT, because mpz_export only write the minimum
> > -     number of bytes, including none if our value is zero!  */
> > -  T result = 0;
> > +  T result;
> >
> > -  gdb_mpz exported_val (val);
> > -  if (std::is_signed<T>::value && mpz_cmp_ui (val, 0) < 0)
> > -    {
> > -      /* We want to use mpz_export to set the return value, but
> > -	 this function does not handle the sign. So give exported_val
> > -	 a value which is at the same time positive, and has the same
> > -	 bit representation as our negative value.  */
> > -      gdb_mpz neg_offset;
> > +  this->safe_export (gdb::make_array_view ((gdb_byte *) &result,
> > +					   sizeof (result)),
> 
> I'd suggest using
> 
>   {(gdb_byte *) &result, sizeof (result)}
> 
> to make the array view, as suggested by Pedro earlier.

I thought I had tried that and got an error, but I will try again.

-- 
Joel

  reply	other threads:[~2020-12-01  3:37 UTC|newest]

Thread overview: 140+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-08  6:30 RFA: Add support for DWARF-based fixed point types Joel Brobecker
2020-11-08  6:30 ` [PATCH 1/9] gdb/configure: Add --with-libgmp-prefix option Joel Brobecker
2020-11-08  6:30 ` [PATCH 2/9] gdb: Make GMP a required dependency for building GDB Joel Brobecker
2020-12-15  6:55   ` Sebastian Huber
2020-12-15  8:57     ` Joel Brobecker
2020-11-08  6:30 ` [PATCH 3/9] gmp-utils: New API to simply use of GMP's integer/rational/float objects Joel Brobecker
2020-11-10 20:15   ` Simon Marchi
2020-11-13  8:12     ` Joel Brobecker
2020-11-13 15:04       ` Tom Tromey
2020-11-13 15:06         ` Simon Marchi
2020-11-16 16:18         ` Tom Tromey
2020-11-16 16:34   ` Luis Machado
2020-11-18  3:52     ` Joel Brobecker
2020-11-08  6:30 ` [PATCH 4/9] Move uinteger_pow gdb/valarith.c to gdb/utils.c and make it public Joel Brobecker
2020-11-08  6:30 ` [PATCH 5/9] Add support for printing value of DWARF-based fixed-point type objects Joel Brobecker
2020-11-10 21:06   ` Simon Marchi
2020-11-14 10:48     ` Joel Brobecker
2020-11-14 13:20       ` Simon Marchi
2020-11-14 11:30     ` Joel Brobecker
2020-11-14 16:14       ` Simon Marchi
2020-11-15  5:30         ` Joel Brobecker
2020-11-15  6:33     ` Joel Brobecker
2020-11-16  0:13       ` Simon Marchi
2020-11-08  6:30 ` [PATCH 6/9] fix printing of DWARF fixed-point type objects with format modifier Joel Brobecker
2020-11-10 22:50   ` Simon Marchi
2020-11-08  6:30 ` [PATCH 7/9] Add ptype support for DWARF-based fixed-point types Joel Brobecker
2020-11-10 23:00   ` Simon Marchi
2020-11-15  6:57     ` Joel Brobecker
2020-11-15  7:09       ` Joel Brobecker
2020-11-16  0:16         ` Simon Marchi
2020-11-16  4:03           ` Joel Brobecker
2020-11-08  6:30 ` [PATCH 8/9] Add support for fixed-point type arithmetic Joel Brobecker
2020-11-10 23:18   ` Simon Marchi
2020-11-08  6:30 ` [PATCH 9/9] Add support for fixed-point type comparison operators Joel Brobecker
2020-11-10 23:21 ` RFA: Add support for DWARF-based fixed point types Simon Marchi
2020-11-11  4:53   ` Joel Brobecker
2020-11-15  8:35 ` pushed: " Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 1/9] gdb/configure: Add --with-libgmp-prefix option Joel Brobecker
2020-11-15 15:52     ` Bernd Edlinger
2020-11-16  3:45       ` Joel Brobecker
2020-11-16 14:20         ` Bernd Edlinger
2020-11-17  7:41           ` [PATCH] Enable GDB build with in-tree GMP and MPFR Bernd Edlinger
2020-11-18  3:44             ` Joel Brobecker
2020-11-18  8:14               ` Bernd Edlinger
2020-12-01 19:29                 ` Bernd Edlinger
2020-12-01 19:32                   ` Simon Marchi
2020-12-01 19:38                     ` Bernd Edlinger
2020-12-01 20:29                       ` Bernd Edlinger
2020-12-01 20:30                         ` Simon Marchi
2020-12-02  3:21                           ` Joel Brobecker
2020-12-08 20:39                             ` [PING] " Bernd Edlinger
2020-12-14 17:40                         ` [PATCH v2] " Bernd Edlinger
2020-12-14 18:47                           ` Simon Marchi
2020-12-14 21:35                             ` Tom Tromey
2020-12-14 22:17                               ` Simon Marchi
2020-12-15  2:33                                 ` Joel Brobecker
2020-12-15 14:39                                   ` Simon Marchi
2020-12-15 16:24                                     ` Bernd Edlinger
2020-12-16  7:33                                     ` Joel Brobecker
2020-12-16 18:16                                       ` Bernd Edlinger
2020-12-25 12:05                                         ` Bernd Edlinger
2020-12-27 22:01                                           ` Simon Marchi
2020-12-29  8:36                                             ` Bernd Edlinger
2020-12-29 14:50                                               ` Simon Marchi
2021-01-10 14:12                                                 ` Bernd Edlinger
2021-01-10 15:32                                                   ` Simon Marchi
2021-01-11  3:22                                                   ` Joel Brobecker
2021-01-16 18:01                                                     ` Bernd Edlinger
2020-12-15 15:33                                 ` Bernd Edlinger
2020-12-15 15:10                             ` Bernd Edlinger
2020-11-15  8:35   ` [pushed/v2 2/9] gdb: Make GMP a required dependency for building GDB Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 3/9] gmp-utils: New API to simply use of GMP's integer/rational/float objects Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 4/9] Move uinteger_pow gdb/valarith.c to gdb/utils.c and make it public Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 5/9] Add support for printing value of DWARF-based fixed-point type objects Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 6/9] fix printing of DWARF fixed-point type objects with format modifier Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 7/9] Add ptype support for DWARF-based fixed-point types Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 8/9] Add support for fixed-point type arithmetic Joel Brobecker
2020-11-15  8:35   ` [pushed/v2 9/9] Add support for fixed-point type comparison operators Joel Brobecker
2020-11-16 23:48   ` pushed: Add support for DWARF-based fixed point types Pedro Alves
2020-11-17 14:25     ` Simon Marchi
2020-11-18  3:47       ` Joel Brobecker
2020-11-22 13:12         ` [RFA] Add TYPE_CODE_FIXED_POINT handling in print_type_scalar Joel Brobecker
2020-11-22 14:35           ` Simon Marchi
2020-11-24  3:04             ` Joel Brobecker
2020-11-22 14:00         ` pushed: Add support for DWARF-based fixed point types Joel Brobecker
2020-11-22 20:11           ` Simon Marchi
2020-11-23  4:27             ` Joel Brobecker
2020-11-23 16:12               ` Simon Marchi
2020-11-24  2:39                 ` Joel Brobecker
2020-11-29 15:45               ` RFA: wrap mpz_export into gdb_mpz::safe_export Joel Brobecker
2020-11-29 15:45                 ` [RFA 1/2] Fix TARGET_CHAR_BIT/HOST_CHAR_BIT confusion in gmp-utils.c Joel Brobecker
2020-11-30 15:42                   ` Simon Marchi
2020-12-05  8:05                     ` Joel Brobecker
2020-11-29 15:45                 ` [RFA 2/2] gmp-utils: protect gdb_mpz exports against out-of-range values Joel Brobecker
2020-11-30 15:56                   ` Simon Marchi
2020-12-01  3:37                     ` Joel Brobecker [this message]
2020-12-01  4:02                       ` Simon Marchi
2020-12-01  7:11                         ` Joel Brobecker
2020-12-05  8:10                   ` [RFAv2 " Joel Brobecker
2020-12-05 23:26                     ` Simon Marchi
2020-12-06  4:58                       ` Joel Brobecker
2020-11-30 12:44                 ` RFA: wrap mpz_export into gdb_mpz::safe_export Christian Biesinger
2020-11-20 14:08   ` pushed: Add support for DWARF-based fixed point types Pedro Alves
2020-11-20 14:14     ` Joel Brobecker
2020-11-22 11:56   ` RFA/doco: Various changes related to GMP and fixed point type support Joel Brobecker
2020-11-22 11:56     ` [RFA/doco 1/4] gdb/NEWS: Document that building GDB now requires GMP Joel Brobecker
2020-11-22 15:31       ` Eli Zaretskii
2020-11-24  3:11         ` Joel Brobecker
2020-11-22 11:56     ` [RFA/doco 2/4] gdb/NEWS: Document that GDB now supports DWARF-based fixed point types Joel Brobecker
2020-11-22 15:33       ` Eli Zaretskii
2020-11-24  3:12         ` Joel Brobecker
2020-11-22 11:56     ` [RFA/doco 3/4] gdb/README: Document the --with-libgmp-prefix configure option Joel Brobecker
2020-11-22 15:32       ` Eli Zaretskii
2020-11-24  3:11         ` Joel Brobecker
2020-11-22 11:56     ` [RFA/doco 4/4] gdb/README: Fix the URL of the MPFR website (now https) Joel Brobecker
2020-11-22 15:33       ` Eli Zaretskii
2020-11-24  3:11         ` Joel Brobecker
2020-11-15  8:49 ` RFA: Various enhancements to the fixed-point support implementation Joel Brobecker
2020-11-15  8:49   ` [RFA 1/6] change gmp_string_asprintf to return an std::string Joel Brobecker
2020-11-16  0:41     ` Simon Marchi
2020-11-16  3:55       ` Joel Brobecker
2020-11-16 20:10         ` Simon Marchi
2020-11-15  8:49   ` [RFA 2/6] gmp-utils: Convert the read/write methods to using gdb::array_view Joel Brobecker
2020-11-16  0:52     ` Simon Marchi
2020-11-16 23:05       ` Pedro Alves
2020-11-17 14:32         ` Simon Marchi
2020-11-15  8:49   ` [RFA 3/6] gdbtypes.h: Get rid of the TYPE_FIXED_POINT_INFO macro Joel Brobecker
2020-11-15  8:49   ` [RFA 4/6] Make fixed_point_type_base_type a method of struct type Joel Brobecker
2020-11-15  8:49   ` [RFA 5/6] Make function fixed_point_scaling_factor " Joel Brobecker
2020-11-15  8:49   ` [RFA 6/6] valarith.c: Replace INIT_VAL_WITH_FIXED_POINT_VAL macro by lambda Joel Brobecker
2020-11-16  1:01   ` RFA: Various enhancements to the fixed-point support implementation Simon Marchi
2020-11-22 11:14   ` RFA v2: " Joel Brobecker
2020-11-22 11:14     ` [RFA v2 1/6] change and rename gmp_string_asprintf to return an std::string Joel Brobecker
2020-11-22 11:14     ` [RFA v2 2/6] gmp-utils: Convert the read/write methods to using gdb::array_view Joel Brobecker
2020-11-22 11:14     ` [RFA v2 3/6] gdbtypes.h: Get rid of the TYPE_FIXED_POINT_INFO macro Joel Brobecker
2020-11-22 11:14     ` [RFA v2 4/6] Make fixed_point_type_base_type a method of struct type Joel Brobecker
2020-11-22 11:14     ` [RFA v2 5/6] Make function fixed_point_scaling_factor " Joel Brobecker
2020-11-22 11:14     ` [RFA v2 6/6] valarith.c: Replace INIT_VAL_WITH_FIXED_POINT_VAL macro by lambda Joel Brobecker
2020-11-23 16:46     ` RFA v2: Various enhancements to the fixed-point support implementation Simon Marchi
2020-11-24  2:56       ` Joel Brobecker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201201033725.GA3501@adacore.com \
    --to=brobecker@adacore.com \
    --cc=gdb-patches@sourceware.org \
    --cc=simark@simark.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).