memdup(zend_ast_ref)

From: Date: Mon, 27 Feb 2023 20:36:14 +0000
Subject: memdup(zend_ast_ref)
Groups: php.internals 
Request: Send a blank email to internals+get-119609@lists.php.net to get a copy of this message
Hi, today, I stumbled on this piece of code in zend_persist.c: zend_ast_ref *old_ref = Z_AST_P(z); Z_AST_P(z) = zend_shared_memdup_put(Z_AST_P(z), sizeof(zend_ast_ref)); This is the definition of zend_ast_ref from zend_types.h: struct _zend_ast_ref { zend_refcounted_h gc; /*zend_ast ast; zend_ast follows the zend_ast_ref structure */ }; The memdup() call confuses me. It looks broken. It appears that code which allocates zend_ast_ref reserves some space after that for one or more zend_ast instances, see zend_ast_copy() and create_enum_case_ast(). But what happens if I memdup() only the raw zend_ast_ref, which consists of only the zend_refcounted_h? What confuses me even more is that zend_persist.c then calls zend_persist_ast() to copy one zend_ast that follows after the zend_ast_ref object, but discards the newly allocated value. Not only does this look like a memory leak, but also the zend_ast_ref is incomplete, and dereferencing the following zend_ast should be an out-of-bounds access. Does this piece of code rely on the next zend_shared_memdup() call to place the next allocation right after the zend_ast_ref? (This sounds pretty fragile. What happens if padding happens to get inserted by the allocator?) Max

« previous php.internals (#119609) next »