From 08841bf79c8fe4dba42dcd7f180cb82a079cf9aa Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sun, 25 Aug 2024 13:06:30 +0200 Subject: [PATCH] Fix GH-15552: Signed integer overflow in ext/standard/scanf.c We ensure that the argnum `value` is in the allowed range, *before* mapping it to the `objIndex`, not *afterwards*. Closes GH-15581. --- NEWS | 3 +++ ext/standard/scanf.c | 4 ++-- ext/standard/tests/strings/gh15552.phpt | 9 +++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 ext/standard/tests/strings/gh15552.phpt diff --git a/NEWS b/NEWS index 9921764951f..a56df16f5e6 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,9 @@ PHP NEWS . Fixed bug GH-15432 (Heap corruption when querying a vector). (cmb, Kamil Tekiela) +- Standard: + . Fixed bug GH-15552 (Signed integer overflow in ext/standard/scanf.c). (cmb) + - Streams: . Fixed bug GH-15628 (php_stream_memory_get_buffer() not zero-terminated). (cmb) diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index 78ecc1642cf..408e5ede888 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -361,8 +361,7 @@ PHPAPI int ValidateFormat(char *format, int numVars, int *totalSubs) if (gotSequential) { goto mixedXPG; } - objIndex = value - 1; - if ((objIndex < 0) || (numVars && (objIndex >= numVars))) { + if ((value < 1) || (numVars && (value > numVars))) { goto badIndex; } else if (numVars == 0) { /* @@ -382,6 +381,7 @@ PHPAPI int ValidateFormat(char *format, int numVars, int *totalSubs) xpgSize = (xpgSize > value) ? xpgSize : value; } + objIndex = value - 1; goto xpgCheckDone; } diff --git a/ext/standard/tests/strings/gh15552.phpt b/ext/standard/tests/strings/gh15552.phpt new file mode 100644 index 00000000000..60804e025d8 --- /dev/null +++ b/ext/standard/tests/strings/gh15552.phpt @@ -0,0 +1,9 @@ +--TEST-- +Bug GH-15552 (Signed integer overflow in ext/standard/scanf.c) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ValueError: "%n$" argument index out of range in %s:%d +Stack trace:%A