[php-src] PHP-8.4.24: Fix out-of-bounds write in ext-bcmath bccomp() via bc_str2num()

"Recep A. via Ilija Tovilo" <[email protected]> Wed, 29 Jul 2026 05:23:37 +0000
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Recep A. (recepasan)
Committer: Ilija Tovilo (iluuu1994)
Pusher: NattyNarwhal
Date: 2026-07-28T11:09:58+02:00

Commit: https://github.com/php/php-src/commit/fa18dab73f9340448c0d5c0a1d75d3fec844b358
Raw diff: https://github.com/php/php-src/commit/fa18dab73f9340448c0d5c0a1d75d3fec844b358.diff

Fix out-of-bounds write in ext-bcmath bccomp() via bc_str2num()

When a fraction is truncated to a caller-supplied scale and then re-trimmed of
trailing zeros, str_scale was reduced but fractional_end was not, so
bc_copy_and_toggle_bcd() copied more bytes than were reserved by
bc_new_num_nonzeroed(). With small numbers allocated from the 256-byte stack
arena this is a stack-based OOB write reachable via bccomp($num1, $num2,
$scale), e.g. bccomp("1.901", "0", 2).

Keep fractional_end in sync with str_scale so the copy length matches the
reserved length.

Fixes GHSA-x692-q9x7-8c3f

Changed paths:
  A  ext/bcmath/tests/GHSA-x692-q9x7-8c3f.phpt
  M  ext/bcmath/libbcmath/src/str2num.c


Diff:

diff --git a/ext/bcmath/libbcmath/src/str2num.c b/ext/bcmath/libbcmath/src/str2num.c
index bd9a44a24050..3b99065b43fb 100644
--- a/ext/bcmath/libbcmath/src/str2num.c
+++ b/ext/bcmath/libbcmath/src/str2num.c
@@ -181,6 +181,7 @@ bool bc_str2num(bc_num *num, const char *str, const char *end, size_t scale, siz
 			if (str_scale > 0) {
 				const char *fractional_new_end = bc_skip_zero_reverse(fractional_end, fractional_ptr);
 				str_scale -= fractional_end - fractional_new_end; /* fractional_end >= fractional_new_end */
+				fractional_end = fractional_new_end;
 			}
 		}
 	} else {
diff --git a/ext/bcmath/tests/GHSA-x692-q9x7-8c3f.phpt b/ext/bcmath/tests/GHSA-x692-q9x7-8c3f.phpt
new file mode 100644
index 000000000000..b735958bd07a
--- /dev/null
+++ b/ext/bcmath/tests/GHSA-x692-q9x7-8c3f.phpt
@@ -0,0 +1,13 @@
+--TEST--
+GHSA-x692-q9x7-8c3f: bccomp() out-of-bounds write
+--CREDITS--
+Recep Asan (recepasan)
+--FILE--
+<?php
+
+$n = '1.' . '9' . str_repeat('0', 300) . '1';
+var_dump(bccomp($n, '0', 300));
+
+?>
+--EXPECT--
+int(1)