Repository navigation
Conversation
…/fastcover
In COVER_ctx_init() and FASTCOVER_ctx_init(), totalSamplesSize is
verified against MAX(d, sizeof(U64)), but trainingSamplesSize is never
checked. When splitPoint < 1.0, trainingSamplesSize is computed from
the first nbTrainSamples samples only. If trainingSamplesSize is
smaller than MAX(d, sizeof(U64)), computing ctx->suffixSize and
ctx->nbDmers:
trainingSamplesSize - MAX(d, sizeof(U64)) + 1
underflows size_t to a value near SIZE_MAX. This leads to massive
out-of-bounds heap operations and crashes.
Additionally, in COVER_computeEpochs():
1. If k == 0 or passes == 0, maxDictSize / k / passes triggers a
SIGFPE division by zero.
2. If nbDmers == 0, epochs.size evaluates to 0, causing a subsequent
nbDmers / epochs.size SIGFPE division by zero.
3. If epochs.num ever evaluated to 0, callers computing
(epoch + 1) % epochs.num would trigger modulo by zero.
Fix both issues by:
- Rejecting trainingSamplesSize < MAX(d, sizeof(U64)) with
ERROR(srcSize_wrong) in COVER_ctx_init and FASTCOVER_ctx_init.
- Hardening COVER_computeEpochs against zero values for k, passes,
and epochs.size, guaranteeing epochs.num >= 1.
- Adding regression tests to tests/fuzzer.c.
Signed-off-by: Filippo Tedeschi <filippotedeschi98@gmail.com>
Author
|
Closing. I tried the case this describes (cover and fastCover, splitPoint 0.75, |
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
This PR addresses two security and stability defects in
lib/dictBuilder/cover.candlib/dictBuilder/fastcover.c:Unchecked
trainingSamplesSizeInteger Underflow & Buffer Overflow:In
COVER_ctx_init()andFASTCOVER_ctx_init(),totalSamplesSizeis verified againstMAX(d, sizeof(U64)), buttrainingSamplesSizeis never checked.When
splitPoint < 1.0(which is standard practice and the default inFASTCOVERwhereFASTCOVER_DEFAULT_SPLITPOINT = 0.75),trainingSamplesSizeis calculated solely from the sum of the firstnbTrainSamplessamples.If
trainingSamplesSize < MAX(d, sizeof(U64)), calculating:cover.c:ctx->suffixSize = trainingSamplesSize - MAX(d, sizeof(U64)) + 1;fastcover.c:ctx->nbDmers = trainingSamplesSize - MAX(d, sizeof(U64)) + 1;causes unsigned integer underflow on
size_t(e.g.5 - 8 + 1wraps around toSIZE_MAX - 1). Incover.c, this results in an oversized allocation or integer multiplication overflow inmalloc(ctx->suffixSize * sizeof(U32)), followed by an out-of-bounds heap write loop inctx->suffix[i] = i;. Infastcover.c,ctx->nbDmerswrapping leads to out-of-bounds loop bounds and crashes.Hardware Division by Zero in
COVER_computeEpochs():In
COVER_computeEpochs():k == 0orpasses == 0,maxDictSize / k / passescauses aSIGFPEdivision by zero.nbDmers == 0,epochs.size = MIN(minEpochSize, nbDmers)evaluates to0, causing aSIGFPEdivision by zero onepochs.num = nbDmers / epochs.size.epochs.numis now guaranteed to be >= 1, preventing any downstream modulo-by-zero crashes infor (epoch = 0; tail > 0; epoch = (epoch + 1) % epochs.num).Changes
trainingSamplesSize < MAX(d, sizeof(U64))in bothCOVER_ctx_init()andFASTCOVER_ctx_init()withERROR(srcSize_wrong).COVER_computeEpochs()to safely handle zero values fork,passes,nbDmers, andepochs.size, ensuringepochs.num >= 1.tests/fuzzer.cto verify thatZDICT_optimizeTrainFromBuffer_cover()andZDICT_optimizeTrainFromBuffer_fastCover()properly reject inputs with underflowing training sample sizes.