178eeb
From ea1e86cfdf26a330e58ea377a80273de7110011b Mon Sep 17 00:00:00 2001
178eeb
From: Tony Cook <tony@develop-help.com>
178eeb
Date: Wed, 21 Aug 2019 11:37:58 +1000
178eeb
Subject: [PATCH] disallow vstring magic strings over 2GB-1
178eeb
MIME-Version: 1.0
178eeb
Content-Type: text/plain; charset=UTF-8
178eeb
Content-Transfer-Encoding: 8bit
178eeb
178eeb
On reads this could result in buffer overflows, so avoid writing
178eeb
such large vstrings to avoid causing problems for older Storable.
178eeb
178eeb
Since we no longer write such large vstrings, we don't want to accept
178eeb
them.
178eeb
178eeb
I doubt that restricting versions strings to under 2GB-1 will have
178eeb
a practical effect on downstream users.
178eeb
178eeb
fixes #17306
178eeb
178eeb
Signed-off-by: Petr Písař <ppisar@redhat.com>
178eeb
---
178eeb
 dist/Storable/Storable.xs | 19 ++++++++++++++++---
178eeb
 1 file changed, 16 insertions(+), 3 deletions(-)
178eeb
178eeb
diff --git a/dist/Storable/Storable.xs b/dist/Storable/Storable.xs
178eeb
index c2335680ab..d27ac58012 100644
178eeb
--- a/dist/Storable/Storable.xs
178eeb
+++ b/dist/Storable/Storable.xs
178eeb
@@ -2628,6 +2628,12 @@ static int store_scalar(pTHX_ stcxt_t *cxt, SV *sv)
178eeb
             /* The macro passes this by address, not value, and a lot of
178eeb
                called code assumes that it's 32 bits without checking.  */
178eeb
             const SSize_t len = mg->mg_len;
178eeb
+            /* we no longer accept vstrings over I32_SIZE-1, so don't emit
178eeb
+               them, also, older Storables handle them badly.
178eeb
+            */
178eeb
+            if (len >= I32_MAX) {
178eeb
+                CROAK(("vstring too large to freeze"));
178eeb
+            }
178eeb
             STORE_PV_LEN((const char *)mg->mg_ptr,
178eeb
                          len, SX_VSTRING, SX_LVSTRING);
178eeb
         }
178eeb
@@ -5937,12 +5943,19 @@ static SV *retrieve_lvstring(pTHX_ stcxt_t *cxt, const char *cname)
178eeb
 {
178eeb
 #ifdef SvVOK
178eeb
     char *s;
178eeb
-    I32 len;
178eeb
+    U32 len;
178eeb
     SV *sv;
178eeb
 
178eeb
     RLEN(len);
178eeb
-    TRACEME(("retrieve_lvstring (#%d), len = %" IVdf,
178eeb
-             (int)cxt->tagnum, (IV)len));
178eeb
+    TRACEME(("retrieve_lvstring (#%d), len = %" UVuf,
178eeb
+             (int)cxt->tagnum, (UV)len));
178eeb
+
178eeb
+    /* Since we'll no longer produce such large vstrings, reject them
178eeb
+       here too.
178eeb
+    */
178eeb
+    if (len >= I32_MAX) {
178eeb
+        CROAK(("vstring too large to fetch"));
178eeb
+    }
178eeb
 
178eeb
     New(10003, s, len+1, char);
178eeb
     SAFEPVREAD(s, len, s);
178eeb
-- 
178eeb
2.21.0
178eeb