This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
(perl #129149) avoid a heap buffer overflow with pack "W"...
authorTony Cook <tony@develop-help.com>
Wed, 7 Sep 2016 06:51:39 +0000 (16:51 +1000)
committerTony Cook <tony@develop-help.com>
Mon, 16 Jan 2017 22:30:37 +0000 (09:30 +1100)
pp_pack.c
t/op/pack.t

index ee4c69e..737e019 100644 (file)
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -2587,7 +2587,7 @@ S_pack_rec(pTHX_ SV *cat, tempsym_t* symptr, SV **beglist, SV **endlist )
                if (in_bytes) auv = auv % 0x100;
                if (utf8) {
                  W_utf8:
-                   if (cur > end) {
+                   if (cur >= end) {
                        *cur = '\0';
                        SvCUR_set(cat, cur - start);
 
index 3fc12e4..47d1216 100644 (file)
@@ -12,7 +12,7 @@ my $no_endianness = $] > 5.009 ? '' :
 my $no_signedness = $] > 5.009 ? '' :
   "Signed/unsigned pack modifiers not available on this perl";
 
-plan tests => 14712;
+plan tests => 14713;
 
 use strict;
 use warnings qw(FATAL all);
@@ -2047,3 +2047,14 @@ ok(1, "argument underflow did not crash");
     is(pack("H40", $up_nul), $twenty_nuls,
        "check pack H zero fills (utf8 source)");
 }
+
+{
+    # [perl #129149] the code below would write one past the end of the output
+    # buffer, only detected by ASAN, not by valgrind
+    $Config{ivsize} >= 8
+      or skip "[perl #129149] need 64-bit for this test", 1;
+    fresh_perl_is(<<'EOS', "ok\n", { stderr => 1 }, "pack W overflow");
+print pack("ucW", "0000", 0, 140737488355327) eq "\$,#`P,```\n\0\x{7fffffffffff}"
+ ? "ok\n" : "not ok\n";
+EOS
+}