Skip to content

Fix: Check flatbuffer integrity before parsing#1864

Open
AustinBenoit wants to merge 9 commits into
mainfrom
FixVulns
Open

Fix: Check flatbuffer integrity before parsing#1864
AustinBenoit wants to merge 9 commits into
mainfrom
FixVulns

Conversation

@AustinBenoit

Copy link
Copy Markdown
Contributor

Description

Provide details of the change, and generalize the change in the PR title above.
Fix: Check flatbuffer integrity before parsing
Updated flatbuffer to latest version to get verify buffer Use strol for key parsing to ensure exceptions do not result in a crash.


Testing

Describe how you've tested these changes. Link any manually triggered Integration tests or CPP binary SDK Packaging Github Action workflows, if applicable.

Integration test in github


Type of Change

Place an x the applicable box:

  • Bug fix. Add the issue # below if applicable.
  • New feature. A non-breaking change which adds functionality.
  • Other, such as a build process or documentation change.

Notes

  • Bug fixes and feature changes require an update to the Release Notes section of release_build_files/readme.md.
  • Read the contribution guidelines CONTRIBUTING.md.
  • Changes to the public API require an internal API review. If you'd like to help us make Firebase APIs better, please propose your change in a feature request so that we can discuss it together.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates the Flatbuffers dependency to a newer version, removes an obsolete patch file, and improves the robustness of the Remote Config desktop implementation. Specifically, it adds buffer verification before deserializing flexbuffers, enhances file path handling and error checking in the file manager, and replaces std::stoi with safer string-to-integer parsing in the metadata deserialization. The review feedback highlights critical improvements: ensuring robust overflow detection for std::strtol on LLP64 platforms (like Windows) by checking errno, preventing potential undefined behavior from a null package_name(), and explicitly including the necessary and headers.

Comment thread remote_config/src/desktop/metadata.cc
Comment thread remote_config/src/desktop/file_manager.cc Outdated
Comment thread remote_config/src/desktop/metadata.cc
@AustinBenoit AustinBenoit added the tests-requested: full Trigger a FULL set of integration tests (uses expanded test matrix). label Jun 17, 2026
@github-actions github-actions Bot added tests: in-progress This PR's integration tests are in progress. and removed tests-requested: full Trigger a FULL set of integration tests (uses expanded test matrix). labels Jun 17, 2026
@github-actions

github-actions Bot commented Jun 17, 2026

Copy link
Copy Markdown

Integration test with FLAKINESS (but still ⏳  in progress)

Requested by @AustinBenoit on commit acf24f3
Last updated: Thu Jun 18 07:49 PDT 2026
View integration test log & download artifacts

Failures Configs
installations [TEST] [FLAKINESS] [Android] [macos] [emulator_ftl_target]
(1 failed tests)  CRASH/TIMEOUT

Add flaky tests to go/fpl-cpp-flake-tracker

@github-actions github-actions Bot added the tests: failed This PR's integration tests failed. label Jun 17, 2026
@firebase-workflow-trigger firebase-workflow-trigger Bot removed the tests: in-progress This PR's integration tests are in progress. label Jun 17, 2026
@AustinBenoit

Copy link
Copy Markdown
Contributor Author

/gemini review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request updates Flatbuffers to support buffer verification, adds integrity checks to prevent crashes on invalid data, and improves path resolution and error handling in Remote Config. The reviewer feedback highlights a critical bug where a boolean return value is incorrectly compared to nullptr, an issue with an unintended leading slash when the package name is empty, and suggests using default cases instead of case flexbuffers::FBT_MAX_TYPE to robustly handle corrupted or unknown flexbuffer types.

Comment thread app/rest/request_json.h
Comment on lines 68 to +69
bool generate_status =
GenerateText(*parser_, builder.GetBufferPointer(), &json);
GenerateText(*parser_, builder.GetBufferPointer(), &json) == nullptr;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

critical

Comparing the result of GenerateText to nullptr is incorrect. GenerateText returns a bool (indicating success or failure), not a pointer.

Comparing a bool to nullptr will either fail to compile in modern C++ or result in inverted logic (where generate_status becomes false on success and true on failure), causing the subsequent FIREBASE_ASSERT_RETURN_VOID(generate_status) to trigger on successful execution.

We should revert this to simply assign the bool result of GenerateText directly.

Suggested change
bool generate_status =
GenerateText(*parser_, builder.GetBufferPointer(), &json);
GenerateText(*parser_, builder.GetBufferPointer(), &json) == nullptr;
bool generate_status =
GenerateText(*parser_, builder.GetBufferPointer(), &json);

Comment on lines +39 to +41
const char* package_name = app.options().package_name();
std::string app_data_prefix =
std::string(app.options().package_name()) + "/" + app.name();
std::string file_path =
AppDataDir(app_data_prefix.c_str(), /*should_create=*/true) + "/" +
filename;
std::string(package_name ? package_name : "") + "/remote_config";

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

When package_name is null or empty, app_data_prefix is constructed as "/remote_config", which introduces an unintended leading slash. When package_name is present, it is constructed as "package_name/remote_config" (no leading slash).

This inconsistency can cause path resolution issues in AppDataDir (e.g., treating it as an absolute path or causing double slashes). We should ensure that no leading slash is present when package_name is empty or null.

Suggested change
const char* package_name = app.options().package_name();
std::string app_data_prefix =
std::string(app.options().package_name()) + "/" + app.name();
std::string file_path =
AppDataDir(app_data_prefix.c_str(), /*should_create=*/true) + "/" +
filename;
std::string(package_name ? package_name : "") + "/remote_config";
const char* package_name = app.options().package_name();
std::string app_data_prefix =
(package_name && package_name[0] != '\0')
? std::string(package_name) + "/remote_config"
: "remote_config";

Comment thread app/src/variant_util.cc
Comment on lines +253 to +256
case flexbuffers::FBT_MAX_TYPE:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using case flexbuffers::FBT_MAX_TYPE: only handles the specific sentinel value FBT_MAX_TYPE. If the flexbuffer is corrupted or contains an invalid/unknown type ID not covered by the switch, it will bypass this check entirely and silently return Variant::Null().

Using a default: case instead is much more robust as it will catch FBT_MAX_TYPE as well as any other unknown or corrupted type values.

Suggested change
case flexbuffers::FBT_MAX_TYPE:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;
default:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;

Comment on lines +106 to +109
case flexbuffers::FBT_MAX_TYPE:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using case flexbuffers::FBT_MAX_TYPE: only handles the specific sentinel value FBT_MAX_TYPE. If the flexbuffer is corrupted or contains an invalid/unknown type ID not covered by the switch, it will bypass this check entirely and silently return Variant::Null().

Using a default: case instead is much more robust as it will catch FBT_MAX_TYPE as well as any other unknown or corrupted type values.

Suggested change
case flexbuffers::FBT_MAX_TYPE:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;
default:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;

Comment on lines +84 to +87
case flexbuffers::FBT_MAX_TYPE:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

medium

Using case flexbuffers::FBT_MAX_TYPE: only handles the specific sentinel value FBT_MAX_TYPE. If the flexbuffer is corrupted or contains an invalid/unknown type ID not covered by the switch, it will bypass this check entirely and silently return Variant::Null().

Using a default: case instead is much more robust as it will catch FBT_MAX_TYPE as well as any other unknown or corrupted type values.

Suggested change
case flexbuffers::FBT_MAX_TYPE:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;
default:
LogError("Unknown or unsupported flexbuffer type: %d",
static_cast<int>(ref.GetType()));
break;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tests: failed This PR's integration tests failed.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant