Skip to content

Add CRC checks to Svc.PrmDb#4586

Merged
LeStarch merged 13 commits intonasa:develfrom
odacindy-fprime:issue-4270-addCrcChkToPrmDb
Feb 4, 2026
Merged

Add CRC checks to Svc.PrmDb#4586
LeStarch merged 13 commits intonasa:develfrom
odacindy-fprime:issue-4270-addCrcChkToPrmDb

Conversation

@odacindy-fprime
Copy link
Collaborator

Related Issue(s)
Has Unit Tests (y/n)
Documentation Included (y/n)
Generative AI was used in this contribution (y/n)

Change Description

Save and read a CRC to validate the contents of the PrmDb file.

Rationale

Provides protection against corruption

Testing/Review Recommendations

  • made minor updates to TestFile::open, seek, read, and write in order track to the StaticData::data.positionResult, which is used by TestFile::position() to return the current position of the pointer in the paramFile.
  • added file CRC to the beginning of the paramFile
  • added a few unit test cases to check CRC_SIZE, CRC, and CRC_BUFFER on PrmFileReadError, and CRC_PLACE on PrmWriteError; and PrmFileBadCrc

Future Work

none

AI Usage (see policy)

…uns, but without changing the existing unit tests, when I run them, some are now breaking, so will checkpoint now before making changes to existing unit tests
- Change the type for the buff argument in the computeCrc() declaration from "co
nst U8*" to "const BYTE*"

Svc/PrmDb/test/ut/PrmDbTester.cpp
- Update PrmDbTester::runFileReadError() for the following:
  - add a test case for CRC_SIZE when reading the paramFile.
  - add test cases for CRC and CRC_BUFFER for a failed paramFile read due to the
 file not  existing and the file not being opened
  - add a test case for FILE_DATA_ERROR having a bad file CRC when reading a paramFile
- Update PrmDbTester::runFileWriteError() for the following:
  - add test cases for a write failures for CRC when sending the PRM_SAVE_FILE command.
- Update PrmDbTester::PrmDbTestFile::read()'s FILE_SIZE_ERROR case, so that it only increments size (we increment the size to introduce a size error on a paramFile read, which is used for several unit test cases) if size is not zero. If we don't do this, then the unit test will go into an infinite loop, since we may loop multiple  times when reading the CRC buffer (which is part of the paramFile upon which we calculate the CRC. In other words the CRC buffer is the paramFile minus the CRC). The CRC buffer contents contain the param database entries.
- add CURR_POSITION, SEEK_ZERO, and SEEK_POSITION to PrmWriteError enum
- added return status checking for paramFile.seek() and paramFile.position() calls in PrmDbImpl::PRM_SAVE_FILE_cmdHandler()

U32 PrmDbImpl::computeCrc(U32 crc, const BYTE* buff, FwSizeType size) {
for (FwSizeType byte = 0; byte < size; byte++) {
crc = static_cast<U32>(update_crc_32(crc, static_cast<char>(buff[byte])));

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter crc has not been checked.
for (FwSizeType byte = 0; byte < size; byte++) {
crc = static_cast<U32>(update_crc_32(crc, static_cast<char>(buff[byte])));
}
return crc;

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter crc has not been checked.
stat = paramFile.write(reinterpret_cast<const U8*>(&crc), writeSize, Os::File::WaitType::WAIT);
if (stat != Os::File::OP_OK) {
this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::CRC_REAL, 0, stat);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter cmdSeq has not been checked.
paramFile.seek(static_cast<FwSignedSizeType>(currPosInParamFile), Os::File::SeekType::ABSOLUTE);
if (stat != Os::File::OP_OK) {
this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::SEEK_POSITION, 0, stat);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter opCode has not been checked.
paramFile.seek(static_cast<FwSignedSizeType>(currPosInParamFile), Os::File::SeekType::ABSOLUTE);
if (stat != Os::File::OP_OK) {
this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::SEEK_POSITION, 0, stat);
this->cmdResponse_out(opCode, cmdSeq, Fw::CmdResponse::EXECUTION_ERROR);

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter cmdSeq has not been checked.
// seek to beginning and write CRC value
paramFile.seek(0, Os::File::SeekType::ABSOLUTE);
if (stat != Os::File::OP_OK) {
this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::SEEK_ZERO, 0, stat);

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter opCode has not been checked.
// seek to beginning and write CRC value
paramFile.seek(0, Os::File::SeekType::ABSOLUTE);
if (stat != Os::File::OP_OK) {
this->log_WARNING_HI_PrmFileWriteError(PrmWriteError::SEEK_ZERO, 0, stat);

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter cmdSeq has not been checked.
Copy link
Collaborator

@LeStarch LeStarch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor change to the CRC calculation. Hopefully the tests will make this switch easy.

// Check for null pointer before dereferencing
if (buff == nullptr) {
// Return the input CRC unchanged if buffer is null
return crc;

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter crc has not been checked.
return crc;
}

// Check for zero size to avoid unnecessary processing

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter opCode has not been checked.
return crc;
}

// Check for zero size to avoid unnecessary processing

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter cmdSeq has not been checked.

// Check for zero size to avoid unnecessary processing
if (size == 0) {
return crc;

Check warning

Code scanning / CodeQL

Unchecked function argument Warning

This use of parameter crc has not been checked.
}


U32 PrmDbImpl::computeCrc(U32 crc, const BYTE* buff, FwSizeType size) {

Check notice

Code scanning / CodeQL

Long function without assertion Note

All functions of more than 10 lines should have at least one assertion.
@thomas-bc
Copy link
Collaborator

To fix the formatting, you can run this command:

git diff --name-only devel...HEAD | fprime-util format --stdin

@thomas-bc thomas-bc changed the title Issue 4270 add crc chk to prm db Add CRC checks to Svc.PrmDb Jan 22, 2026
LeStarch
LeStarch previously approved these changes Feb 2, 2026
@LeStarch LeStarch merged commit e9dfd3a into nasa:devel Feb 4, 2026
55 of 61 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants