Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix asan stack use after scope (fix #4675) #4676

Merged
merged 5 commits into from
Oct 4, 2023

Conversation

StefanVK
Copy link
Contributor

High Level Overview of Change

Fix asan stack-use-after-scope: #4675

Replace ravlues with lvalues for calls to soci::use to have the scope go beyond the end of the expression.

Context of Change

For insertPeerReservation and deletePeerReservation we could be reading nodeIds that get overwritten while we're reading them.

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

I built rippled with asan with and without the fix. Without the fix asan finds stack-use-after-scope with those commands

./rippled-reporting --start -a
./rippled-reporting peer_reservations_add n9Mxf6qD4J55XeLSCEpqaePW4GjoCR5U1ZeGZGJUCNe3bQa4yQbG 

After the fix, asan no longer reports an issue.

Calling soci::use with rvalues can lead to use of an unnamed tepmporary after its lifetime ended
@ckeshava
Copy link
Collaborator

ckeshava commented Sep 1, 2023

Hello @StefanVK thanks for pointing this out. On which platform/environment did you observe this issue?
I don't understand how the rvalues could suffer from being overwritten in the existing code. My understanding it that the rvalue parameters are being copied into the soci::use() calls.

@StefanVK
Copy link
Contributor Author

StefanVK commented Sep 1, 2023

Hi @ckeshava it was on x86_64 with clang-15 with asan. More details are in the issue #4675

Basically what soci ends up doing is taking a reference to the ravlue in a soci::use_container and then the address in a soci_use_type. It does not copy the value itself and does not extend its lifetime.

The evaluation of the statement is triggered by the destructor of a soci::details::once_temp_type which is the result of operator<< on the soci::session. Other temporaries from the same expression can already be beyond its lifetime at this point.

Now for trivial types such as int it is undefined behavior to access it after the lifetime has ended but realistically you won't see the memory being overwritten within the same statement. For a std::string however when the lifetime ends, the non trivial destructor is invoked and the backing heap memory (for strings too large for small string optimization) gets freed and could be reused by a different thread (depending on the allocator) or another non trivial destructor in the same thread for another object whose lifetime ends in the same statement (not the case for rippled).

I did not observe the memory being overwritten, I only observed asan pointing out that memory is being accessed beyond its lifetime. But I'm convinced that for the std::string case it would be possible for the memory to be overwritten, or for a segmentation fault to occur. We had the same bug in our codebase and I started looking for the same issue in different codebases on github and found rippled.

@ckeshava
Copy link
Collaborator

ckeshava commented Sep 1, 2023

thanks for the detailed explanation @StefanVK It sounds like this is something that needs to be fixed in the soci codebase, but thank you for the fix.

if I want to observe the overwriting of a piece of memory, I'll need to put breakpoints (before and after) and observe certain addresses in the heap right? is there a more efficient way to check this?

@intelliot intelliot requested review from HowardHinnant and removed request for mtrippled September 2, 2023 05:45
@intelliot intelliot added this to the 1.14 milestone Sep 2, 2023
@intelliot
Copy link
Collaborator

@StefanVK: Can you confirm that, from your perspective, this PR still looks good to merge?

@intelliot intelliot modified the milestones: 2024 release, 2.0 Sep 26, 2023
@StefanVK
Copy link
Contributor Author

@intelliot Yes, as far as I'm concerned this is still a correct fix.

@intelliot intelliot merged commit 3dea78d into XRPLF:develop Oct 4, 2023
15 checks passed
florent-uzio pushed a commit to florent-uzio/rippled that referenced this pull request Oct 6, 2023
Address a stack-use-after-scope issue when using rvalues with
`soci::use`. Replace rvalues with lvalues to ensure the scope extends
beyond the end of the expression.

The issue arises from `soci` taking a reference to the rvalue without
copying its value or extending its lifetime. `soci` references rvalues
in `soci::use_container` and then the address in `soci_use_type`. For
types like `int`, memory access post-lifetime is unlikely to cause
issues. However, for `std::string`, the backing heap memory can be freed
and potentially reused, leading to a potential segmentation fault.

This was detected on x86_64 using clang-15 with asan. asan confirms
resolution of the issue.

Fix XRPLF#4675
sophiax851 pushed a commit to sophiax851/rippled that referenced this pull request Jun 12, 2024
Address a stack-use-after-scope issue when using rvalues with
`soci::use`. Replace rvalues with lvalues to ensure the scope extends
beyond the end of the expression.

The issue arises from `soci` taking a reference to the rvalue without
copying its value or extending its lifetime. `soci` references rvalues
in `soci::use_container` and then the address in `soci_use_type`. For
types like `int`, memory access post-lifetime is unlikely to cause
issues. However, for `std::string`, the backing heap memory can be freed
and potentially reused, leading to a potential segmentation fault.

This was detected on x86_64 using clang-15 with asan. asan confirms
resolution of the issue.

Fix XRPLF#4675
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants