From 6a38beea6ad5105f86a2cec0660cad53f511a2f5 Mon Sep 17 00:00:00 2001 From: Walker Date: Wed, 13 May 2026 13:43:44 -0500 Subject: [PATCH 1/3] Part cFS/workflows#129, Use Updated Static Analysis Workflow --- .github/workflows/static-analysis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 9c279a0..85dccf2 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -1,6 +1,5 @@ name: Static Analysis -# Run on all push and pull requests on: push: branches: @@ -16,4 +15,6 @@ on: jobs: static-analysis: name: Static Analysis - uses: nasa/cFS/.github/workflows/app-static-analysis-reusable.yml@dev \ No newline at end of file + uses: nasa/cFS/.github/workflows/static-analysis-reusable.yml@dev + with: + source-dir: 'source/fsw' \ No newline at end of file From 823b5f1396c002ec9270d2afcb0a4480ee117e01 Mon Sep 17 00:00:00 2001 From: Michael Yang Date: Mon, 1 Jun 2026 10:18:31 -0400 Subject: [PATCH 2/3] Fix nasa#139, Suppressed ignored return value warning for CFE_TBL_Load() in FM_TableInit() --- fsw/src/fm_table_utils.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fsw/src/fm_table_utils.c b/fsw/src/fm_table_utils.c index 90c3577..1f5ab96 100644 --- a/fsw/src/fm_table_utils.c +++ b/fsw/src/fm_table_utils.c @@ -55,7 +55,9 @@ CFE_Status_t FM_TableInit(void) if (Status == CFE_SUCCESS) { /* Make an attempt to load the default table data - OK if this fails */ - CFE_TBL_Load(FM_AppData.MonitorTableHandle, CFE_TBL_SRC_FILE, FM_TABLE_DEF_NAME); + /* SAD: Suppress Ignored Return Value warning from CodeSonar. CFE_TBL_Load() will send event message if + * there is any error */ + (void)CFE_TBL_Load(FM_AppData.MonitorTableHandle, CFE_TBL_SRC_FILE, FM_TABLE_DEF_NAME); /* Allow cFE a chance to dump, update, etc. */ FM_AcquireTablePointers(); From ef594678b1d7eae5d1a057e152d57a67fb0e5b48 Mon Sep 17 00:00:00 2001 From: nurdmuny Date: Thu, 11 Jun 2026 06:44:16 -0700 Subject: [PATCH 3/3] fm: handle all CFE_TBL_GetAddress failure codes (not just NEVER_LOADED) Per `cfe_tbl.h`, `CFE_TBL_GetAddress` leaves the table pointer *undefined* on any non-success return. The documented return set is: - CFE_SUCCESS -- pointer set - CFE_TBL_INFO_UPDATED -- pointer set (info code) - CFE_TBL_ERR_NEVER_LOADED -- pointer undefined - CFE_TBL_ERR_INVALID_HANDLE -- pointer undefined - CFE_TBL_ERR_NO_ACCESS -- pointer undefined - CFE_ES_ERR_RESOURCEID_NOT_VALID -- pointer undefined - CFE_TBL_BAD_ARGUMENT -- pointer undefined Three call sites in FM check only `Status == CFE_TBL_ERR_NEVER_LOADED` and dereference `FM_AppData.MonitorTablePtr` in the `else` branch. On any of the other four failure codes (e.g. a table handle that became invalid after a registration churn, or an access-denied caused by an ownership change) the dereference reads an undefined pointer. - fm_cmds.c FM_MonitorFilesystemSpaceCmd ( line ~865 ) - fm_cmds.c FM_SetTableStateCmd ( line ~977 ) - fm_table_utils.c FM_AcquireTablePointers ( line ~216 ) Invert the check at all three sites: the only safe states are `CFE_SUCCESS` and `CFE_TBL_INFO_UPDATED`; everything else NULLs the pointer (and for the two command handlers also sets `CommandResult` false and emits the existing `*_TBL_ERR_EID` error event so the ground operator sees the failure). Same defense-in-depth shape as nasa/MM#116 (DataSize switch with no default case). Surfaced by scj-hunt + Gigi ATTEND on a fresh ingest of FM v1.2.0 into the `cfs_apps_fm_v01` fiber bundle. `FM_SetTableStateCmd` was the rank-1 hit at risk_score 8.8; drilling its structural twins via the ATTEND query surfaced the matching pattern in the other two sites. No new tests added -- the trigger path requires injecting a non-NEVER_LOADED error from `CFE_TBL_GetAddress`, which would need either a mock or a test bench that can fault the handle. Happy to add one if reviewers want. --- fsw/src/fm_cmds.c | 19 ++++++++++++++++--- fsw/src/fm_table_utils.c | 11 +++++++++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/fsw/src/fm_cmds.c b/fsw/src/fm_cmds.c index 1cb8440..9af8634 100644 --- a/fsw/src/fm_cmds.c +++ b/fsw/src/fm_cmds.c @@ -861,8 +861,14 @@ CFE_Status_t FM_MonitorFilesystemSpaceCmd(const FM_MonitorFilesystemSpaceCmd_t * /* Acquire pointer to file system free space table, also locks table */ Status = CFE_TBL_GetAddress((void *)&FM_AppData.MonitorTablePtr, FM_AppData.MonitorTableHandle); - /* Verify that we have a pointer to the file system table data */ - if (Status == CFE_TBL_ERR_NEVER_LOADED) + /* + ** Per cfe_tbl.h, CFE_TBL_GetAddress leaves the table pointer undefined on + ** any non-success return. Only CFE_SUCCESS and CFE_TBL_INFO_UPDATED set + ** the pointer. Prior versions only handled CFE_TBL_ERR_NEVER_LOADED and + ** would dereference an undefined pointer on _INVALID_HANDLE / _NO_ACCESS / + ** CFE_ES_ERR_RESOURCEID_NOT_VALID / CFE_TBL_BAD_ARGUMENT. + */ + if (Status != CFE_SUCCESS && Status != CFE_TBL_INFO_UPDATED) { /* Make sure we don't try to use the empty table buffer */ FM_AppData.MonitorTablePtr = NULL; @@ -974,7 +980,14 @@ CFE_Status_t FM_SetTableStateCmd(const FM_SetTableStateCmd_t *Msg) /* Acquire pointer to file system free space table */ Status = CFE_TBL_GetAddress((void *)&FM_AppData.MonitorTablePtr, FM_AppData.MonitorTableHandle); - if (Status == CFE_TBL_ERR_NEVER_LOADED) + /* + ** Per cfe_tbl.h, CFE_TBL_GetAddress leaves the table pointer undefined on + ** any non-success return. Only CFE_SUCCESS and CFE_TBL_INFO_UPDATED set + ** the pointer. Prior versions only handled CFE_TBL_ERR_NEVER_LOADED and + ** would dereference an undefined pointer on _INVALID_HANDLE / _NO_ACCESS / + ** CFE_ES_ERR_RESOURCEID_NOT_VALID / CFE_TBL_BAD_ARGUMENT. + */ + if (Status != CFE_SUCCESS && Status != CFE_TBL_INFO_UPDATED) { /* Make sure we don't try to use the empty table buffer */ FM_AppData.MonitorTablePtr = NULL; diff --git a/fsw/src/fm_table_utils.c b/fsw/src/fm_table_utils.c index 1f5ab96..d270982 100644 --- a/fsw/src/fm_table_utils.c +++ b/fsw/src/fm_table_utils.c @@ -213,9 +213,16 @@ void FM_AcquireTablePointers(void) /* Acquire pointer to file system free space table */ Status = CFE_TBL_GetAddress((void *)&FM_AppData.MonitorTablePtr, FM_AppData.MonitorTableHandle); - if (Status == CFE_TBL_ERR_NEVER_LOADED) + /* + ** Per cfe_tbl.h, CFE_TBL_GetAddress leaves the table pointer undefined on + ** any non-success return (CFE_TBL_ERR_NEVER_LOADED, _INVALID_HANDLE, + ** _NO_ACCESS, CFE_ES_ERR_RESOURCEID_NOT_VALID, CFE_TBL_BAD_ARGUMENT). + ** Only CFE_SUCCESS and CFE_TBL_INFO_UPDATED set the pointer. NULL out + ** the local copy on any other return so callers see a clean NULL rather + ** than a stale or undefined pointer. + */ + if (Status != CFE_SUCCESS && Status != CFE_TBL_INFO_UPDATED) { - /* Make sure we don't try to use the empty table buffer */ FM_AppData.MonitorTablePtr = NULL; } }