|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
[2022-05-17 09:45 UTC] cmb@php.net
-Status: Open
+Status: Verified
-Assigned To:
+Assigned To: cmb
[2022-05-17 09:45 UTC] cmb@php.net
[2022-05-17 11:17 UTC] c dot fol at ambionics dot io
[2022-05-17 11:35 UTC] cmb@php.net
-Assigned To: cmb
+Assigned To: stas
[2022-05-17 11:35 UTC] cmb@php.net
[2022-05-17 21:16 UTC] stas@php.net
-CVE-ID:
+CVE-ID: needed
[2022-05-25 21:36 UTC] stas@php.net
-CVE-ID: needed
+CVE-ID: 2022-31625
[2022-06-06 07:13 UTC] git@php.net
[2022-06-06 07:13 UTC] git@php.net
-Status: Verified
+Status: Closed
[2022-07-07 13:08 UTC] nutza249943 at gmail dot com
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Fri Oct 24 09:00:01 2025 UTC |
Description: ------------ Hello PHP team, in PHP_FUNCTION(pg_query_params), the array meant to store the char* representation of the query parameters is allocated on the heap, but not cleared: ``` params = (char **)safe_emalloc(sizeof(char *), num_params, 0); ``` If a conversion error happens (for instance, one of the params is an object), `_php_pgsql_free_params()` gets called *on the whole array*. Since the array is not initialized, a lingering value from a previous request can get freed, leading in the end to remote code execution. To patch, use calloc or memset-0 it. There are other functions where you use basically the same code (if cannot convert to string, then free all params) so it might be worth a look. Patch: ``` - _php_pgsql_free_params(params, num_params); + _php_pgsql_free_params(params, i); ``` Best regards, Charles Fol ambionics.io Test script: --------------- <?php $strings = []; function uenc($v) { $out = ''; for($i=0; $i<strlen($v);$i++) { $out .= '\u' . '00' . str_pad(dechex(ord($v[$i])), 2, '0', STR_PAD_LEFT); } return '"' . $out . '"'; } $json = '{"a": 1, "args":[ "A","A","A", {} ]}' ; $c = pg_connect('host=172.17.0.3 user=postgres password=password'); $data = json_decode($json); $resultXXX = pg_query_params($c, 'SELECT * FROM test WHERE x NOT IN ($1)', $data->args); // var_dump(pg_fetch_all($resultXXX)); Expected result: ---------------- No crash. Actual result: -------------- Crash.