create_ticket_api.php (~lines 253-347 and ~457-470): the dedup lookup (SELECT ... WHERE hash = ?) and the subsequent priority-escalation UPDATE run with no transaction or row lock.
Two related failure modes:
Two concurrent hwmonDaemon requests carrying the same dedup hash (e.g. overlapping monitoring runs) can both read the same pre-update snapshot and each independently conclude "priority escalated," each posting its own hwmonDaemon raised priority... comment and firing its own Matrix notification for what is really one escalation event.
On the rarer SELECT→INSERT race (two near-simultaneous creates for the same dedup hash), the loser gets {success:false, error:'Duplicate ticket'} and the request is dropped entirely — it never falls back to applying the priority-escalation/description-refresh logic the normal (non-race) duplicate path performs, so a genuinely-worsening alert that loses the race is silently discarded instead of escalating the existing ticket.
Fix: Wrap the dedup-check + escalate/reopen/insert sequence in a transaction with a row lock (SELECT ... FOR UPDATE) on the matched ticket (or a unique constraint + INSERT ... ON DUPLICATE KEY pattern) so concurrent requests for the same hash serialize correctly instead of racing.
**Severity:** Medium
`create_ticket_api.php` (~lines 253-347 and ~457-470): the dedup lookup (`SELECT ... WHERE hash = ?`) and the subsequent priority-escalation `UPDATE` run with no transaction or row lock.
**Two related failure modes:**
1. Two concurrent hwmonDaemon requests carrying the same dedup hash (e.g. overlapping monitoring runs) can both read the same pre-update snapshot and each independently conclude "priority escalated," each posting its own `hwmonDaemon raised priority...` comment and firing its own Matrix notification for what is really one escalation event.
2. On the rarer SELECT→INSERT race (two near-simultaneous *creates* for the same dedup hash), the loser gets `{success:false, error:'Duplicate ticket'}` and the request is dropped entirely — it never falls back to applying the priority-escalation/description-refresh logic the normal (non-race) duplicate path performs, so a genuinely-worsening alert that loses the race is silently discarded instead of escalating the existing ticket.
**Fix:** Wrap the dedup-check + escalate/reopen/insert sequence in a transaction with a row lock (`SELECT ... FOR UPDATE`) on the matched ticket (or a unique constraint + `INSERT ... ON DUPLICATE KEY` pattern) so concurrent requests for the same hash serialize correctly instead of racing.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Severity: Medium
create_ticket_api.php(~lines 253-347 and ~457-470): the dedup lookup (SELECT ... WHERE hash = ?) and the subsequent priority-escalationUPDATErun with no transaction or row lock.Two related failure modes:
hwmonDaemon raised priority...comment and firing its own Matrix notification for what is really one escalation event.{success:false, error:'Duplicate ticket'}and the request is dropped entirely — it never falls back to applying the priority-escalation/description-refresh logic the normal (non-race) duplicate path performs, so a genuinely-worsening alert that loses the race is silently discarded instead of escalating the existing ticket.Fix: Wrap the dedup-check + escalate/reopen/insert sequence in a transaction with a row lock (
SELECT ... FOR UPDATE) on the matched ticket (or a unique constraint +INSERT ... ON DUPLICATE KEYpattern) so concurrent requests for the same hash serialize correctly instead of racing.