Skip to content

Commit 848f10e

Browse files
authored
[fuzz] Initialize PASE fuzz harness state before the code under test reads it (project-chip#73094)
Two harnesses in FuzzPASE_PW.cpp left an object partially uninitialized before the code they exercise read it, which the OSS-Fuzz memory (MSan) build flagged as use-of-uninitialized-value: - FuzzHandlePBKDFParamResponse prepares the commissioner PASESession by hand and skips Init()/Pair(), which normally set mSetupPINCode. The exercised path HandlePBKDFParamResponse() -> SetupSpake2p() -> Spake2pVerifier::ComputeWS() reads mSetupPINCode, so set a fixed valid passcode in the harness. - FuzzSpake2pVerifier copies fuzzed vectors that may be shorter than mW0[kP256_FE_Length] / mL[kP256_Point_Length] into an uninitialized Spake2pVerifier, leaving the tail bytes unset; BeginVerifier() -> FELoad() later reads them. Zero-initialize the verifier, which keeps the short-input coverage the domains intend. Both are test-harness gaps, not product bugs: production always initializes mSetupPINCode via Init()/Pair(), and production verifiers come from Generate()/Deserialize(), which populate the whole struct.
1 parent fdd6856 commit 848f10e

1 file changed

Lines changed: 7 additions & 1 deletion

File tree

src/protocols/secure_channel/tests/FuzzPASE_PW.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,9 @@ FUZZ_TEST(FuzzPASE_PW, PASESession_Unbounded)
295295
void FuzzSpake2pVerifier(const vector<uint8_t> & aW0, const vector<uint8_t> & aL, const vector<uint8_t> & aSalt,
296296
const uint32_t fuzzedPBKDF2Iter, const uint32_t fuzzedSetupPasscode)
297297
{
298-
Spake2pVerifier fuzzedSpake2pVerifier;
298+
// Zero-initialize: aW0/aL may be shorter than mW0/mL, so the copy_n calls below leave the tail unset and
299+
// BeginVerifier()/FELoad() would read uninitialized bytes. Production verifiers come from Generate()/Deserialize().
300+
Spake2pVerifier fuzzedSpake2pVerifier{};
299301

300302
copy_n(aW0.data(), aW0.size(), fuzzedSpake2pVerifier.mW0);
301303
copy_n(aL.data(), aL.size(), fuzzedSpake2pVerifier.mL);
@@ -495,6 +497,10 @@ void TestPASESession::FuzzHandlePBKDFParamResponse(vector<uint8_t> fuzzPBKDFLoca
495497
memcpy(&pairingCommissioner.mPBKDFLocalRandomData[0], fuzzPBKDFLocalRandomDataInitiator.data(),
496498
fuzzPBKDFLocalRandomDataInitiator.size());
497499

500+
// This harness skips Init()/Pair(), which normally set mSetupPINCode; HandlePBKDFParamResponse() -> ComputeWS()
501+
// reads it. Set a fixed valid passcode (production always initializes it via Init()/Pair()).
502+
pairingCommissioner.mSetupPINCode = 20202021;
503+
498504
// In order to cover the Code path where the Commissioner has PBKDF Parameters before Starting PASE, as such, the Accessory will
499505
// not send the PBKDF Parameters in the Response message
500506
bool initiatorHasPBKDFParams = fuzzHavePBKDFParameters;

0 commit comments

Comments
 (0)