Thread: BUG #17816: Invalid memory access in translate function
The following bug has been logged on the website: Bug reference: 17816 Logged by: Daniil Anisimov Email address: anisimow.d@gmail.com PostgreSQL version: 15.2 Operating system: Ubuntu 22.04.2 LTS Description: When running this query in psql with valgrind-enabled server: select translate('(123)', '()', ''); I get: ==00:00:00:05.576 29520== Invalid read of size 1 ==00:00:00:05.576 29520== at 0x7605BE: pg_utf_mblen (wchar.c:553) ==00:00:00:05.576 29520== by 0x71CEDE: pg_mblen (mbutils.c:968) ==00:00:00:05.576 29520== by 0x67B1E3: translate (oracle_compat.c:864) ==00:00:00:05.576 29520== by 0x3FE8AB: ExecInterpExpr (execExprInterp.c:751) ==00:00:00:05.576 29520== by 0x3FB0B1: ExecInterpExprStillValid (execExprInterp.c:1826) ==00:00:00:05.576 29520== by 0x4EC87F: ExecEvalExprSwitchContext (executor.h:341) ==00:00:00:05.576 29520== by 0x4EC87F: evaluate_expr (clauses.c:4823) ==00:00:00:05.576 29520== by 0x4ECA5B: evaluate_function (clauses.c:4325) ==00:00:00:05.576 29520== by 0x4EEF13: simplify_function (clauses.c:3908) ==00:00:00:05.576 29520== by 0x4ECD1F: eval_const_expressions_mutator (clauses.c:2427) ==00:00:00:05.576 29520== by 0x47DB6C: expression_tree_mutator (nodeFuncs.c:3080) ==00:00:00:05.576 29520== by 0x4EE159: eval_const_expressions_mutator (clauses.c:3527) ==00:00:00:05.576 29520== by 0x47DDB6: expression_tree_mutator (nodeFuncs.c:3166) ==00:00:00:05.576 29520== Address 0x6f541d4 is 7,156 bytes inside a block of size 8,192 alloc'd ==00:00:00:05.576 29520== at 0x4848899: malloc (in /usr/libexec/valgrind/vgpreload_memcheck-amd64-linux.so) ==00:00:00:05.576 29520== by 0x732BCF: AllocSetContextCreateInternal (aset.c:469) ==00:00:00:05.576 29520== by 0x51F8D2: PostmasterMain (postmaster.c:612) ==00:00:00:05.576 29520== by 0x464A71: main (main.c:202) ==00:00:00:05.576 29520== { <insert_a_suppression_name_here> Memcheck:Addr1 fun:pg_utf_mblen fun:pg_mblen fun:translate fun:ExecInterpExpr fun:ExecInterpExprStillValid fun:ExecEvalExprSwitchContext fun:evaluate_expr fun:evaluate_function fun:simplify_function fun:eval_const_expressions_mutator fun:expression_tree_mutator fun:eval_const_expressions_mutator fun:expression_tree_mutator } ==00:00:00:05.576 29520== ==00:00:00:05.576 29520== Exit program on first error (--exit-on-first-error=yes) In the translate() function in src/backend/utils/adt/oracle_compat.c used pg_mblen(p) even if p has zero length: for (i = 0; i < from_index; i++) { p += pg_mblen(p); if (p >= (to_ptr + tolen)) break; } These changes fix the issue: for (i = 0; i < from_index; i++) { if (p >= (to_ptr + tolen)) break; p += pg_mblen(p); }
PG Bug reporting form <noreply@postgresql.org> writes: > When running this query in psql with valgrind-enabled server: > select translate('(123)', '()', ''); > I get: > ==00:00:00:05.576 29520== Invalid read of size 1 > ==00:00:00:05.576 29520== at 0x7605BE: pg_utf_mblen (wchar.c:553) > ==00:00:00:05.576 29520== by 0x71CEDE: pg_mblen (mbutils.c:968) > ==00:00:00:05.576 29520== by 0x67B1E3: translate (oracle_compat.c:864) Thanks for the report! > These changes fix the issue: > for (i = 0; i < from_index; i++) > { > if (p >= (to_ptr + tolen)) > break; > p += pg_mblen(p); > } Yeah, I agree, we need to switch the order of those two statements. Will fix. (Might be worth pulling out the common subexpression here? I wonder if all compilers are smart enough to evaluate to_ptr + to_len just once.) regards, tom lane