From b1d1be046d050f905a581bce0cbbee4386953a52 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 26 Oct 2024 12:31:12 +0200 Subject: [PATCH] Fix GH-16589: UAF in SplDoublyLinked->serialize() --- ext/spl/spl_dllist.c | 9 ++++++++- ext/spl/tests/gh16589.phpt | 23 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 ext/spl/tests/gh16589.phpt diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 6592efc4e5e4e..612fe2a7ed954 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -44,10 +44,13 @@ PHPAPI zend_class_entry *spl_ce_SplStack; efree(elem); \ } -#define SPL_LLIST_CHECK_DELREF(elem) if ((elem) && !--SPL_LLIST_RC(elem)) { \ +#define SPL_LLIST_CHECK_DELREF_EX(elem, on_free) if ((elem) && !--SPL_LLIST_RC(elem)) { \ efree(elem); \ + on_free \ } +#define SPL_LLIST_CHECK_DELREF(elem) SPL_LLIST_CHECK_DELREF_EX(elem, ;) + #define SPL_LLIST_ADDREF(elem) SPL_LLIST_RC(elem)++ #define SPL_LLIST_CHECK_ADDREF(elem) if (elem) SPL_LLIST_RC(elem)++ @@ -1024,8 +1027,12 @@ PHP_METHOD(SplDoublyLinkedList, serialize) smart_str_appendc(&buf, ':'); next = current->next; + SPL_LLIST_CHECK_ADDREF(next); + php_var_serialize(&buf, ¤t->data, &var_hash); + SPL_LLIST_CHECK_DELREF_EX(next, break;); + current = next; } diff --git a/ext/spl/tests/gh16589.phpt b/ext/spl/tests/gh16589.phpt new file mode 100644 index 0000000000000..7b1452e37a461 --- /dev/null +++ b/ext/spl/tests/gh16589.phpt @@ -0,0 +1,23 @@ +--TEST-- +GH-16589 (UAF in SplDoublyLinked->serialize()) +--CREDITS-- +chibinz +--FILE-- +pop(); + return []; + } +} + +$list = new SplDoublyLinkedList; +$list->add(0, new C); +$list->add(1, 1); +var_dump($list->serialize()); + +?> +--EXPECT-- +string(17) "i:0;:O:1:"C":0:{}"