-
Notifications
You must be signed in to change notification settings - Fork 560
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Assertion failure in Perl_sv_vcatpvfn_flags (sv.c:13127) #16881
Comments
From @dur-randirCreated by @dur-randirWhile fuzzing perl v5.29.8-21-gde59f38ed9 built with afl and run printf q)%7000000000E)=> to cause an assertion failure perl: sv.c:13127: Perl_sv_vcatpvfn_flags: Assertion `elen >= width' failed. GDB stack trace is following: #0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50 This is a regression between 5.26 and 5.28, bisect points to commit 5860c1e S_expect_number(): return STRLEN not I32 This static function is used by Perl_sv_vcatpvfn_flags() to read in Change it to return STRLEN, and to croak on the value being greater than Perl Info
|
From @tonycozOn Fri, 08 Mar 2019 15:36:30 -0800, randir wrote:
The bug causing this is this code: if (width) { since base is an int, the very large 7000000000 becomes a largish negative But fixing that reveals a different issue. The return type of v?snprintf() is int, so such a large result can't be reported So fail earlier than this by checking the expected width fits in an int. Tony |
From @tonycoz0001-perl-133913-limit-numeric-format-results-to-INT_MAX.patchFrom 24d96eaa52130354efe282f202083d6e8dd7549d Mon Sep 17 00:00:00 2001
From: Tony Cook <tony@develop-help.com>
Date: Wed, 20 Mar 2019 16:47:49 +1100
Subject: (perl #133913) limit numeric format results to INT_MAX
The return value of v?snprintf() is int, and we pay attention to that
return value, so limit the expected size of numeric formats to
INT_MAX.
---
pod/perldiag.pod | 6 ++++++
sv.c | 7 +++++++
t/op/sprintf2.t | 7 +++++++
3 files changed, 20 insertions(+)
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 8163dde583..125afe66b4 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -4346,6 +4346,12 @@ the meantime, try using scientific notation (e.g. "1e6" instead of
a number. This happens, for example with C<\o{}>, with no number between
the braces.
+=item Numeric format result too large
+
+(F) The length of the result of a numeric format supplied to sprintf()
+or printf() would have been too large for the underlying C function to
+report. This limit is typically 2GB.
+
=item Octal number > 037777777777 non-portable
(W portable) The octal number you specified is larger than 2**32-1
diff --git a/sv.c b/sv.c
index e9a46827d3..53dad06889 100644
--- a/sv.c
+++ b/sv.c
@@ -13080,6 +13080,13 @@ Perl_sv_vcatpvfn_flags(pTHX_ SV *const sv, const char *const pat, const STRLEN p
if (float_need < width)
float_need = width;
+ if (float_need > INT_MAX) {
+ /* snprintf() returns an int, and we use that return value,
+ so die horribly if the expected size is too large for int
+ */
+ Perl_croak(aTHX_ "Numeric format result too large");
+ }
+
if (PL_efloatsize <= float_need) {
/* PL_efloatbuf should be at least 1 greater than
* float_need to allow a trailing \0 to be returned by
diff --git a/t/op/sprintf2.t b/t/op/sprintf2.t
index 3f4c126c68..eda4e67e99 100644
--- a/t/op/sprintf2.t
+++ b/t/op/sprintf2.t
@@ -1141,4 +1141,11 @@ foreach(
is sprintf("%.0f", $_), sprintf("%-.0f", $_), "special-case %.0f on $_";
}
+# large uvsize needed so the large width is parsed properly
+# large sizesize needed so the STRLEN check doesn't
+if ($Config{intsize} == 4 && $Config{uvsize} > 4 && $Config{sizesize} > 4) {
+ eval { my $x = sprintf("%7000000000E", 0) };
+ like($@, qr/^Numeric format result too large at /,
+ "croak for very large numeric format results");
+}
done_testing();
--
2.11.0
|
The RT System itself - Status changed from 'new' to 'open' |
From @iabynOn Tue, Mar 19, 2019 at 11:01:08PM -0700, Tony Cook via RT wrote:
Your suggested patch looks good to me. -- |
From @dur-randirCan this patch be applied now? |
From @tonycozOn Wed, 01 May 2019 05:55:57 -0700, davem wrote:
Applied in 027471c. Thanks for the report and the reminder. Tony |
@tonycoz - Status changed from 'open' to 'pending release' |
Migrated from rt.perl.org#133913 (status was 'pending release')
Searchable as RT133913$
The text was updated successfully, but these errors were encountered: