Prevent the number of buckets in a hash from getting too large

This commit is contained in:
Petr Písař 2021-03-04 17:39:11 +01:00
parent 4f72402355
commit 622440427f
2 changed files with 60 additions and 0 deletions

View File

@ -0,0 +1,53 @@
From c5eed6e541fe27d9e9dfd31f42c43f4dfa1f486b Mon Sep 17 00:00:00 2001
From: Yves Orton <demerphq@gmail.com>
Date: Sat, 11 Jul 2020 09:26:21 +0200
Subject: [PATCH] hv.c: add a guard clause to prevent the number of buckets in
a hash from getting too large
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This caps it at 1<<28 buckets, eg, ~268M. In theory without a guard clause like
this we could grow to the point of possibly wrapping around in terms of size,
not to mention being ridiculously wasteful of memory at larger sizes.
Even this cap is probably too high. It should probably be something like 1<<24.
Petr Písař: Ported to 5.32.1 from
aae087f7cec022be14a17deb95cb2208e16b7891.
Signed-off-by: Petr Písař <ppisar@redhat.com>
---
hv.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/hv.c b/hv.c
index eccae62..32dbd19 100644
--- a/hv.c
+++ b/hv.c
@@ -38,7 +38,13 @@ holds the key and hash value.
* NOTE if you change this formula so we split earlier than previously
* you MUST change the logic in hv_ksplit()
*/
-#define DO_HSPLIT(xhv) ( ((xhv)->xhv_keys + ((xhv)->xhv_keys >> 1)) > (xhv)->xhv_max )
+
+/* MAX_BUCKET_MAX is the maximum max bucket index, at which point we stop growing the
+ * number of buckets,
+ */
+#define MAX_BUCKET_MAX ((1<<26)-1)
+#define DO_HSPLIT(xhv) ( ( ((xhv)->xhv_keys + ((xhv)->xhv_keys >> 1)) > (xhv)->xhv_max ) && \
+ ((xhv)->xhv_max < MAX_BUCKET_MAX) )
#define HV_FILL_THRESHOLD 31
static const char S_strtab_error[]
@@ -1426,6 +1432,8 @@ S_hsplit(pTHX_ HV *hv, STRLEN const oldsize, STRLEN newsize)
);
PERL_ARGS_ASSERT_HSPLIT;
+ if (newsize > MAX_BUCKET_MAX+1)
+ return;
PL_nomemok = TRUE;
Renew(a, PERL_HV_ARRAY_ALLOC_BYTES(newsize)
--
2.26.2

View File

@ -265,6 +265,10 @@ Patch53: perl-5.33.6-Add-missing-entries-to-perldiag-GH-18276.patch
# in upstream after 5.33.6
Patch54: perl-5.33.6-t-run-locale.t-Rmv-LANGUAGE-from-environment.patch
# Prevent the number of buckets in a hash from getting too large,
# in upstream after 5.33.6
Patch55: perl-5.32.1-hv.c-add-a-guard-clause-to-prevent-the-number-of-buc.patch
# Link XS modules to libperl.so with EU::CBuilder on Linux, bug #960048
Patch200: perl-5.16.3-Link-XS-modules-to-libperl.so-with-EU-CBuilder-on-Li.patch
@ -4320,6 +4324,7 @@ you're not running VMS, this module does nothing.
%patch52 -p1
%patch53 -p1
%patch54 -p1
%patch55 -p1
%patch200 -p1
%patch201 -p1
@ -4373,6 +4378,7 @@ perl -x patchlevel.h \
'Fedora Patch52: Fix PERL_UNUSED_ARG() definition in XSUB.h' \
'Fedora Patch53: Add missing entries to perldiag (GH#18276)' \
'Fedora Patch54: Protect locale tests from LANGUAGE environment variable' \
'Fedora Patch55: Prevent the number of buckets in a hash from getting too large' \
'Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux' \
'Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux' \
%{nil}
@ -7102,6 +7108,7 @@ popd
%changelog
* Thu Mar 04 2021 Petr Pisar <ppisar@redhat.com> - 4:5.32.1-472
- Protect locale tests from LANGUAGE environment variable
- Prevent the number of buckets in a hash from getting too large
* Tue Feb 09 2021 Petr Pisar <ppisar@redhat.com> - 4:5.32.1-471
- Make accessing environment by DynaLoader thread-safe