UBSAN crash in EventTriggerCollectAlterTSConfig (memcpy with NULL src)
Florin Irion <irionr@gmail.com>
From: Florin Irion <irionr@gmail.com>
To: pgsql-hackers@lists.postgresql.org
Cc: Álvaro Herrera <alvherre@kurilemu.de>
Date: 2026-03-03T17:33:40Z
Lists: pgsql-hackers
Attachments
- v1-0001-Add-regression-test-for-EventTriggerCollectAlterT.patch (text/plain) patch v1-0001
- v1-0002-Fix-UBSAN-crash-in-EventTriggerCollectAlterTSConf.patch (text/plain) patch v1-0002
Hi,
While working on the pg_get_domain_ddl() patch [1], I installed an
event trigger on ddl_command_end in test_setup.sql to automatically
round-trip DDL. This triggered a UBSAN crash on CI [2] that turns out
to be a pre-existing bug since b488c580aef(?).
The DROP MAPPING code path in tsearchcmds.c unconditionally calls:
```
EventTriggerCollectAlterTSConfig(stmt, cfgId, NULL, 0);
```
Inside EventTriggerCollectAlterTSConfig(), this reaches:
```
command->d.atscfg.dictIds = palloc_array(Oid, ndicts); /* ndicts=0 */
memcpy(command->d.atscfg.dictIds, dictIds, sizeof(Oid) * ndicts);
^^^^^^^ NULL
```
Under -fsanitize=undefined this triggers SIGABRT and crashes the server.
The bug has been latent for 11 years because without an active event
trigger, currentEventTriggerState is NULL and the function returns early
at the top, never reaching the memcpy. The standard regression suite
never had an event trigger installed during the tsdicts test — until now.
Reproducer (crashes only under UBSAN) and patch attached:
This affects all branches back to 9.5 where b488c580aef landed.
[1] https://www.postgresql.org/message-id/CAPgqM1V4LW2qiDLPsusb7s0kYbSDJjH5Tt%2B-ZzVmPU7xV0TJNQ%40mail.gmail.com
[2] https://cirrus-ci.com/task/6170470552174592
--
Cheers,
Florin
EDB -- www.enterprisedb.com
Commits
-
Don't malloc(0) in EventTriggerCollectAlterTSConfig
- e2ee58eec079 18.4 landed
- e0a9c6463509 14.23 landed
- ce4fbe1ac6e9 19 (unreleased) landed
- 988b9588dadb 15.18 landed
- 616798d0114a 17.10 landed
- 46c54d3d2f3e 16.14 landed