From 5f7eb6bbbe0510964e3fb1d6bb691e5445913e55 Mon Sep 17 00:00:00 2001
From: "Paul \"LeoNerd\" Evans" <leonerd@leonerd.org.uk>
Date: Sat, 9 May 2026 17:18:43 +0100
Subject: [PATCH] pp_pack.c: Avoid ssize_t overflow when calculating the size
 of a structure

If the user has requested a size that would overflow a SSize_t, then the
only sensible thing to do is throw an exception, because the structure
this implies couldn't possibly fit into memory anyway.

CVE: CVE-2026-57432
Upstream-Status: Backport [https://github.com/Perl/perl5/commit/5f7eb6bbbe0510964e3fb1d6bb691e5445913e55]
Signed-off-by: Jaipaul Cheernam <jaipaul.cheernam@est.tech>
---
 pod/perldiag.pod | 6 ++++++
 pp_pack.c        | 4 ++++
 2 files changed, 10 insertions(+)

diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index 841e22d580..d9231077363d 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -4880,6 +4880,12 @@ mixed-case attribute name, instead.  See L<attributes>.
 (F) You can't specify a repeat count so large that it overflows your
 signed integers.  See L<perlfunc/pack>.
 
+=item Pack template structure size is too large
+
+(F) You called C<pack> or C<unpack> to operate on a structure, whose
+computed size is too large to fit in memory.  This usually happens as a
+result of embedding a large number as the repeat count for an item.
+
 =item page overflow
 
 (W io) A single call to write() produced more lines than can fit on a
diff --git a/pp_pack.c b/pp_pack.c
index b5c0b261ef..6075e83aac 100644
--- a/pp_pack.c
+++ b/pp_pack.c
@@ -528,6 +528,10 @@ S_measure_struct(pTHX_ tempsym_t* symptr)
                 break;
             }
         }
+        if ((size > 0) &&
+                ((len > SSize_t_MAX / size) ||         /* detect overflow of len * size */
+                 (len * size > SSize_t_MAX - total)))  /* detect overflow of total + len * size */
+            croak("Pack template structure size is too large");
         total += len * size;
     }
     return total;
-- 
2.43.0
