Subject: bug#13827: closed (Re: bug#13827: faulty range check in bytevector accessor)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 20 Jun 2016 15:17:02 +0000

Your bug report

#13827: faulty range check in bytevector accessor

which was filed against the guile package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
13827: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=13827
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#13827: faulty range check in bytevector accessor
From: Andy Wingo <[email-masked]>
To: "Ben Rocer" <[email-masked]>
Cc: [email-masked]
Date: Mon, 20 Jun 2016 17:16:05 +0200
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi!

Thank you very much for the bug report and fix!  Applied to master, will
be part of 2.1.4.

Cheers,

Andy

On Mon 28 Jul 2014 16:35, "Ben Rocer" <[email-masked]> writes:

> [resubmitting to [email-masked] as debbugs seems to have eaten my
>  first mail]
>
> When I tried to reproduce this bug on a 32-bit x86 system, I got an
> abort in the function bytevector_large_set(); I think this is also
> where the bug is.
>
> Specifically, there are two bugs in these two consecutive lines in
> bytevector_large_set():
>
> value_size = (mpz_sizeinbase (c_mpz, 2) + (8 * c_size)) / (8 * c_size);
> if (SCM_UNLIKELY (value_size > c_size))
>
> In the first line, there is an off-by-one error in the calculation of
> value_size; it gives the wrong answer if mpz_sizeinbase() is a
> multiple of (8 * c_size) (see
> https://gmplib.org/manual/Integer-Import-and-Export.html).
>
> Secondly, this calculation gives the number of (c_size-byte) *words*
> required to hold c_mpz, not the number of bytes. So the check in the
> next line should be (c_size * value_size > c_size), or equivalently
> (value_size > 1).
>
> Since bytevector-u64-set! also calls bytevector_large_set, it
> may be possible to reproduce this bug on 64 bit systems too; e.g
> (bytevector-u64-set! (make-bytevector 8) 0 (expt 2 64) (endianness big))
> [untested]
>
>
> --- a/libguile/bytevectors.c
> +++ b/libguile/bytevectors.c
> @@ -867,10 +867,10 @@ bytevector_large_set (char *c_bv, size_t c_size, int signed_p,
>      memset (c_bv, 0, c_size);
>    else
>      {
> -      size_t word_count, value_size;
> +      size_t word_count, value_words;
>  
> -      value_size = (mpz_sizeinbase (c_mpz, 2) + (8 * c_size)) / (8 * c_size);
> -      if (SCM_UNLIKELY (value_size > c_size))
> +      value_words = (mpz_sizeinbase (c_mpz, 2) + (8 * c_size) - 1) / (8 * c_size);
> +      if (SCM_UNLIKELY (value_words > 1))
>  	{
>  	  err = -2;
>  	  goto finish;

Subject: faulty range check in bytevector accessor
From: Ian Price <[email-masked]>
To: [email-masked]
Date: Wed, 27 Feb 2013 02:02:06 +0000
List-Id: <debbugs-submit.debbugs.gnu.org>

Branch: master
Commit: 9b977c836bf147d386944c401113aba32776fa68
System: 32 bit x86 Fedora 16

(use-modules (rnrs bytevectors))
(define not-32-bit (expt 2 32))
(define bv (make-bytevector 4))
(bytevector-u32-set! bv 0 not-32-bit (endianness big))
(pk bv)

Running this gives me a core dump. It happens for a wide range of values
that don't fit in 32 bits.

After some talk on #guile, Mark and I believe it comes down to the range
check in INTEGER_ACCESSOR_PROLOGUE in bytevectors.c

-- 
Ian Price -- shift-reset.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"