{
  "number": 5262,
  "title": "FileUplink::File::open: validate destination path length at entry",
  "url": "https://github.com/nasa/fprime/pull/5262",
  "state": "closed",
  "merged": true,
  "merged_at": "2026-06-09T23:33:55Z",
  "merge_commit_sha": "96187b70c1f4929ae27f99e351f08486ba9d265e",
  "checked_at": "2026-10-15",
  "body": "| | |\n|:---|:---|\n|**_Related Issue(s)_**| #5261 |\n|**_Has Unit Tests (y/n)_**| n |\n|**_Documentation Included (y/n)_**| n |\n|**_Generative AI was used in this contribution (y/n)_**| n |\n\n---\n## Change Description\n\nAdds a local `length >= sizeof(path)` bound check at the entry of `FileUplink::File::open`, returning `Os::File::Status::BAD_SIZE` when the supplied destination path length would overflow the 256-byte stack buffer.\n\n## Rationale\n\nThe function copies wire-supplied bytes into a fixed 256-byte local buffer using `memcpy(path, ..., length)` with no local comparison between `length` and `sizeof(path)`. Current safety relies on `Fw::FilePacket::PathName::m_length` being declared `U8` (in a different file), capping `length` at 255 \u2264 `MAX_LENGTH`. Any future widening of `m_length` to `U16` or `U32` would silently turn this into a remotely-triggerable stack buffer overflow, with no compiler error and no test failure unless someone happened to test with a path longer than 255 bytes.\n\nDefense-in-depth here matches the existing style of `handleDataPacket` in the same component, which performs explicit overflow + bound checks against `byteOffset + dataSize` even though both operands are already `U32`-bounded by their declared types.\n\nCloses #5261.\n\n## Testing/Review Recommendations\n\n- Review the choice of return code (`Os::File::Status::BAD_SIZE` from `Os/File.hpp:45`). `BAD_SIZE` is the closest existing semantic match; `OTHER_ERROR` is the fallback if `BAD_SIZE` is reserved for a different use.\n- The change is one defensive comparison + early return; no functional behavior changes on well-formed inputs.\n- Existing unit tests in `Svc/FileUplink/test/` should continue to pass since well-formed StartPackets have `length <= 255 < 256 = sizeof(path)`.\n\nA unit test exercising the new error path (a hand-constructed StartPacket whose PathName length would equal or exceed `sizeof(path)`) would be valuable, but constructing such a StartPacket requires loosening the upstream `U8` constraint or going below the public API \u2014 happy to add this if the maintainers can advise on the preferred approach.\n\n## Future Work\n\nIf the maintainer team is interested, the same defensive style applies to a small handful of other functions in `Svc/CmdSequencer/` and `Svc/FileDownlink/` where path or string fields are similarly memcpy'd into fixed-size buffers relying on upstream type narrowing. Happy to scope a follow-up sweep.\n\n## AI Usage (see [policy](https://github.com/nasa/fprime/blob/devel/AI_POLICY.md))\n\nn/a\n",
  "files": [
    {
      "filename": "Svc/FileUplink/File.cpp",
      "patch": "@@ -20,6 +20,10 @@ namespace Svc {\n Os::File::Status FileUplink::File::open(const Fw::FilePacket::StartPacket& startPacket) {\n     const U32 length = startPacket.getDestinationPath().getLength();\n     char path[Fw::FilePacket::PathName::MAX_LENGTH + 1];\n+    // Ensure that length is not greater that the size of the variable we will copy into\n+    if (length >= sizeof(path)) {\n+        return Os::File::Status::BAD_SIZE;\n+    }\n     memcpy(path, startPacket.getDestinationPath().getValue(), length);\n     path[length] = 0;\n     Fw::LogStringArg logStringArg(path);",
      "blob_url": "https://github.com/nasa/fprime/blob/f0e97c65094902149171d9114a14a2fce805ec42/Svc%2FFileUplink%2FFile.cpp"
    }
  ],
  "reviews": [
    {
      "user": "LeStarch",
      "state": "APPROVED",
      "body": "",
      "url": "https://github.com/nasa/fprime/pull/5262#pullrequestreview-4463291123"
    }
  ],
  "comments": [],
  "review_comments": []
}
