sc: do not publish uninitialised TblPtrNew when CFE_TBL_GetAddress fails#170
sc: do not publish uninitialised TblPtrNew when CFE_TBL_GetAddress fails#170nurdymuny wants to merge 7 commits into
Conversation
Reset MISSION_REV to 0xFF and build number to 1.
Initiate post v7.0.1 development cycle
…use-updated-static-analysis-workflow Part cFS/workflows#129, Use Updated Static Analysis Workflow
Changes the definition to the proper "default" pattern which allows the value to be overridden on a mission config basis.
Fix nasa#162, change RTS IDs to correct pattern
`SC_ManageTable` re-acquires a table address after `CFE_TBL_Manage`:
void *TblPtrNew;
...
Result = CFE_TBL_GetAddress(&TblPtrNew, TblHandle);
*TblAddr = TblPtrNew; /* sets this to NULL if it fails */
The inline comment is wrong. Per `cfe_tbl.h`, `CFE_TBL_GetAddress`
leaves the output pointer **undefined** on any non-success return,
not NULL. Documented failures:
- CFE_TBL_ERR_NEVER_LOADED
- CFE_TBL_ERR_INVALID_HANDLE
- CFE_TBL_ERR_NO_ACCESS
- CFE_ES_ERR_RESOURCEID_NOT_VALID
- CFE_TBL_BAD_ARGUMENT
Only `CFE_SUCCESS` and `CFE_TBL_INFO_UPDATED` set the pointer.
`TblPtrNew` is a local declared without initialiser. On any of the
failure paths above the unconditional `*TblAddr = TblPtrNew;` writes
whatever was on the stack at that slot into
`SC_OperData.AtsTblAddr[i]` / `RtsTblAddr[i]` / `AppendTblAddr`.
Subsequent code in `sc_loads.c`, `sc_atsrq.c`, and `sc_cmds.c` reads
those slots via `SC_GetAtsEntryAtOffset(...)` and dereferences a wild
pointer.
Fix:
1. Initialise `TblPtrNew = NULL` before the call so a failing
`CFE_TBL_GetAddress` cannot leave stack garbage in it.
2. Only publish `TblPtrNew` to `*TblAddr` on `CFE_SUCCESS` or
`CFE_TBL_INFO_UPDATED`; otherwise write NULL so downstream code
sees a clean NULL (which it can null-check) rather than a wild
pointer.
3. Remove the misleading inline comment and document the actual
`cfe_tbl.h` contract.
Same defense-in-depth shape as nasa/MM#116 (DataSize switch with no
default case) and nasa/FM#143 (the analogous narrow-error check in
`FM_SetTableStateCmd` / `FM_MonitorFilesystemSpaceCmd` /
`FM_AcquireTablePointers`).
Surfaced by scj-hunt + Gigi ATTEND on the `cfs_apps_sc_v01` fiber
bundle. `SC_ManageTable` ranked in the top cluster at risk_score
8.8; the underlying mistake about the `CFE_TBL_GetAddress` contract
was the same root cause as the FM finding.
|
FYI to reviewers: while sweeping the cFS apps for the same shape, I found that if (status < CFE_SUCCESS) { /* error */ }(negative-only check) as the safest pattern, on the basis that cFE convention is "alt-success codes are positive, errors are negative". If you'd prefer that idiom over the explicit allow-list in this PR ( Also worth noting: I dug into |
Summary
SC_ManageTablere-acquires a table address afterCFE_TBL_Managebut writes the returned pointer into the sharedSC_OperData.*TblAddrslot unconditionally, before checking the return code:The inline comment is wrong. Per
cfe_tbl.h,CFE_TBL_GetAddressleaves the output pointer undefined on any non-success return — onlyCFE_SUCCESSandCFE_TBL_INFO_UPDATEDset it. The five failure codes (CFE_TBL_ERR_NEVER_LOADED,_INVALID_HANDLE,_NO_ACCESS,CFE_ES_ERR_RESOURCEID_NOT_VALID,CFE_TBL_BAD_ARGUMENT) all skip the write.TblPtrNewis declared atsc_cmds.c:723without an initialiser, so on any failure path the*TblAddr = TblPtrNew;write publishes whatever was on the stack at that slot intoSC_OperData.AtsTblAddr[i](or RTS / Append). Downstream code insc_loads.c,sc_atsrq.c, andsc_cmds.creads those slots viaSC_GetAtsEntryAtOffset(...)and dereferences a wild pointer.Change
TblPtrNew = NULLbefore the call so a failingCFE_TBL_GetAddresscannot leave stack garbage in it.TblPtrNewto*TblAddronCFE_SUCCESSorCFE_TBL_INFO_UPDATED; otherwise writeNULL.cfe_tbl.hcontract.Provenance
Surfaced by scj-hunt + Gigi ATTEND on the
cfs_apps_sc_v01fiber bundle.SC_ManageTableranked in the top cluster at risk_score 8.8; the underlying mistake about theCFE_TBL_GetAddresscontract was the same root cause as the FM finding in nasa/FM#143 — both files (and others) over-narrow the failure-code check. Same defense-in-depth shape as nasa/MM#116 (DataSize switch with no default case).scj-hunt is open source at nurdymuny/shadow-clone-jutsu.
Test plan
CFE_TBL_GetAddresswithCFE_TBL_ERR_INVALID_HANDLE, observe that the sharedSC_OperData.AtsTblAddr[i]slot is set toNULL(cleanly null-checkable) instead of leaving stack garbage there forSC_GetAtsEntryAtOffsetto dereference.🤖 Generated with Claude Code