[ML] Fail gracefully when restoring a categorizer with an out-of-range token ID - #3143
Open
edsavage wants to merge 4 commits into
Open
[ML] Fail gracefully when restoring a categorizer with an out-of-range token ID#3143edsavage wants to merge 4 commits into
edsavage wants to merge 4 commits into
Conversation
…e token ID An inconsistent or truncated categorizer state document can leave a restored category referencing a token ID at or beyond the end of the restored token ID lookup. That ID was later used to index the token ID lookup unchecked (for example when building a reverse search), which is an out-of-bounds access that can crash the autodetect process with a SIGSEGV inside libc rather than failing the restore. Validate, at the end of CTokenListDataCategorizerBase::acceptRestoreTraverser, that every token ID referenced by a restored category exists in the restored token ID lookup, and fail the restore gracefully if not. This is consistent with the graceful invalid-state handling added in elastic#2895/elastic#2898. Relates to elastic#2875 Co-authored-by: Cursor <cursoragent@cursor.com>
|
Pinging @elastic/ml-core (Team:ML) |
|
Hi @edsavage, I've created a changelog YAML for you. |
A category's ordered common token begin/end indices are restored directly from the state document and used to index the category's base token list unchecked (for example in updateOrderedCommonTokenIds and containsCommonInOrderTokensInOrder). A corrupt or truncated state can set an end index beyond the base token list, causing an out-of-bounds access. Extend the restore validation to also require, per category, that the ordered common token bounds describe a valid sub-range of the base token list (begin <= end <= baseTokenIds().size()), failing the restore gracefully otherwise. Relates to elastic#2875 Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.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
Fixes a residual native crash (SIGSEGV) when restoring a categorizer from an inconsistent or truncated state document, seen on a
9.6.0-SNAPSHOTbuild (see #2875).CTokenListDataCategorizerBase::acceptRestoreTraverserrestores a list of tokens (m_TokenIdLookup) and a list of categories. Each restored category references token IDs (its base and common-unique token IDs). Those IDs are later used to indexm_TokenIdLookupwithout a bounds check — e.g. incacheReverseSearch:m_TokenIdLookupis a Boost multi-index container whose random-accessoperator[]performs no bounds checking. If a corrupt/truncated state leaves a category referencing a token ID at or beyond the end of the restored lookup, this is an out-of-bounds access that returns a garbageCTokenInfoItem; calling.str()on it then dereferences a bogus pointer, crashing theautodetectprocess with a SIGSEGV inside libc (strlen/memcpy) rather than failing the restore.This matches the crash signature reported in #2875 on 9.6:
si_signo 11,si_code 1(SEGV_MAPERR), crash PC inlibc.so.6. The graceful invalid-state handling added in #2895 / #2898 does not cover this particular path.Fix
Validate, at the end of
acceptRestoreTraverser, that every token ID referenced by a restored category exists in the restored token ID lookup. If any is out of range, log an error and fail the restore gracefully (returningfalse), consistent with the intent of #2895 / #2898, instead of proceeding with an inconsistent state that crashes later.Testing
Added two unit tests in
CTokenListDataCategorizerTest:testRestoreWithInconsistentTokenIdFailsGracefully— a state with a single token but a category referencing token ID 5; restore now returnsfalse(previously undefined behaviour / crash).testRestoreWithConsistentTokenIdSucceeds— a valid state referencing the only valid token ID (0) still restores successfully, confirming the new check does not reject good state.Both pass, along with the existing
testPersistround-trip test (so valid states are unaffected).Relates to #2875