Repository navigation
fix(game): close DataPack ownership leaks - #1571
Merged
Merged
Conversation
Rushaway
added a commit
to srcdslab/sourcebans-pp
that referenced
this pull request
Sep 22, 2026
Companion to the DataPack/Timer/KeyValues handle-leak sweep already on this branch: upstream sbpp#1571 ("close DataPack ownership leaks") also fixed a second, distinct bug class in the same functions that this branch's earlier commits didn't cover - stale client-index reuse across an async DB round trip. Every ban command (sm_ban, sm_banip, sm_addban, sm_unban) and the target-list/time/reason menu flow packs the issuing admin's (and, for the menu flow, the target's) raw client index into a DataPack or a per-slot global array, then reads it back after an async SQL query or after the admin steps through several menu screens. SourceMod reuses a freed client slot immediately, so if the original admin or target disconnects in that window and a different player connects into the same slot, the stale index now points at an unrelated player. The existing IsClientInGame()/IsClientConnected() guards can't tell "still the same player" from "someone else now" - only a userid survives a disconnect/reconnect as a stable identity. sbpp_comms.sp already carries this pattern (Query_UnBlockSelect reads adminUserID/targetUserID and resolves via GetClientOfUserId()); this port brings sbpp_main.sp's ban flow in line with it: - New g_BanTargetUserId[] parallels g_BanTarget[]/g_BanTime[] so the target-list -> time -> reason menu chain (ReasonSelected, HackingSelected, ChatHook's own-reason path) re-validates the target's userid in PrepareBan() before banning, instead of trusting a live-looking but possibly-reused client index. - CommandBanIp/CommandUnban/CommandAddBan now pack the admin's userid instead of the raw index; SelectBanIpCallback, InsertBanIpCallback, SelectUnbanCallback, InsertUnbanCallback, SelectAddbanCallback and InsertAddbanCallback all resolve it back via GetClientOfUserId() before using it for ShowActivity2()/LogAction()/PrintToChat() - the existing "admin && IsClientInGame(admin)" guards stay correct as-is since GetClientOfUserId() returns 0 for a slot that moved on. - VerifyInsert (both the success path and the primary-DB-failure path that falls back to the SQLite queue) and UTIL_InsertTempBan now re-resolve admin from the adminUserId field the pack already carried but discarded, and UTIL_InsertTempBan additionally re-resolves the target from targetUserId before deciding whether to kick them. - Native_SBBanPlayer's PrepareBan() call passes the target's current userid, which is a no-op validation there since the call is synchronous - kept for signature consistency and because the native is public API third-party plugins call. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
8 tasks
Rushaway
added a commit
to srcdslab/sourcebans-pp
that referenced
this pull request
Sep 22, 2026
…bpp#1571/sbpp#1572 Two bugs surfaced while comparing this fork's Synergy/queue-related plugin fixes against upstream sbpp#1572 ("use native auth ids for engine bans") — upstream's diff touches the same functions and happens to carry the fix for the first one as a side effect. 1. ProcessQueueCallback re-INSERTs a matured queue row into the main `%!s_bans` table, but was building and executing that query against `db` — the local SQLite queue connection this callback fires on (bound via SQLiteDB.Query(ProcessQueueCallback, ...) in ProcessQueue()) — instead of `DB`, the main panel database the `%!s_bans` table actually lives on. SQLite has no such table, so the INSERT would fail every time; AddedFromSQLiteCallback's `results == null` branch just re-arms the temporary in-game hold and leaves the row in the queue, so the ban would keep getting re-enforced locally but NEVER actually land in the permanent database once it came back up after an outage — silently defeating the entire point of the offline queue. Switched both the `.Format()` call (MySQL vs SQLite escaping rules differ) and the final `.Query()` to `DB`. Paired with a `DB == INVALID_HANDLE` guard at the top of the callback (matching upstream) so this doesn't trade "silently fails forever" for "throws a native error" on a cycle where the main DB is still down. 2. AddedFromSQLiteCallback's success path calls `RemoveBan(auth, BANFLAG_AUTHID)` with the raw Steam2 identity to clear the temporary in-game hold once the real ban lands in the main database. But the temp hold was created by SBPP_BanIdentity(), which converts to SteamID3 whenever it can (some engines, e.g. Synergy, reject the STEAM_ format for the "banid" console command, so SBPP_BanIdentity works around it) — a Steam2-only RemoveBan() call silently misses a SteamID3-keyed entry, leaving a stale temporary ban sitting in SourceMod's cache until it expires on its own. Try the SteamID3 form too; removing an identity with no matching ban is a harmless no-op. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
DataPackvalues and their nested reason packsTempUnBlockTesting
sbpp_*.spplugin with SourcePawn 1.12.0.7253Closes #1570