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