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(spanner): avoid use-after-move bugs #7588

Merged
merged 2 commits into from
Nov 13, 2021

Conversation

devjgm
Copy link
Contributor

@devjgm devjgm commented Nov 12, 2021

@devbww and I debugged a use-after move issue that boiled down to these
two Row iterators inspecting a data member (e.g., row_ and tup_) on
subsequent invocations of op++, after a caller may have rightfully
moved the object. To avoid this issue, we keep an extra bool in both
iterators to avoid the need to inspect the StatusOr data member again.

Note: This issue didn't show up in our code or builds. It showed up only
when trying to make a different change to Status.

Kudos to @devbww for helping to track this down.


This change is Reviewable

@devbww and I debugged a use-after move issue that boiled down to these
two Row iterators inspecting a data member (e.g., `row_` and `tup_`) on
subsequent invocations of `op++`, after a caller may have rightfully
moved the object. To avoid this issue, we keep an extra bool in both
iterators to avoid the need to inspect the StatusOr data member again.

Note: This issue didn't show up in our code or builds. It showed up only
when trying to make a different change to `Status`.

Kudos to @devbww for helping to track this down.
@devjgm devjgm requested a review from a team as a code owner November 12, 2021 23:18
@product-auto-label product-auto-label bot added the api: spanner Issues related to the Spanner API. label Nov 12, 2021
@google-cla google-cla bot added the cla: yes This human has signed the Contributor License Agreement. label Nov 12, 2021
@devjgm devjgm requested a review from devbww November 12, 2021 23:19
@google-cloud-cpp-bot
Copy link
Collaborator

Google Cloud Build Logs
For commit: c59b98c1ddc4e785db00e46ed39edeb50b109104

ℹ️ NOTE: Kokoro logs are linked from "Details" below.

TEST(TupleStreamIterator, MovedFromValueOk) {
std::vector<Row> rows;
rows.emplace_back(MakeTestRow({{"num", Value(42)}}));
rows.emplace_back(MakeTestRow({{"num", Value(42)}}));
Copy link
Contributor

Choose a reason for hiding this comment

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

Use a distinct value?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

EXPECT_NE(it, end);
auto row = std::move(*it);
EXPECT_STATUS_OK(row);
EXPECT_EQ(1, row->size());
Copy link
Contributor

Choose a reason for hiding this comment

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

Look at the values?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

@codecov
Copy link

codecov bot commented Nov 12, 2021

Codecov Report

Merging #7588 (8428356) into main (83656ab) will increase coverage by 0.00%.
The diff coverage is 100.00%.

Impacted file tree graph

@@           Coverage Diff           @@
##             main    #7588   +/-   ##
=======================================
  Coverage   95.24%   95.24%           
=======================================
  Files        1252     1252           
  Lines      112850   112894   +44     
=======================================
+ Hits       107483   107529   +46     
+ Misses       5367     5365    -2     
Impacted Files Coverage Δ
google/cloud/spanner/row.cc 94.23% <100.00%> (+0.11%) ⬆️
google/cloud/spanner/row.h 100.00% <100.00%> (ø)
google/cloud/spanner/row_test.cc 100.00% <100.00%> (ø)
...le/cloud/spanner/database_admin_connection_test.cc 99.20% <0.00%> (-0.50%) ⬇️
...le/cloud/storage/internal/curl_download_request.cc 89.25% <0.00%> (-0.38%) ⬇️
google/cloud/pubsub/samples/samples.cc 92.02% <0.00%> (-0.08%) ⬇️
google/cloud/completion_queue_test.cc 97.14% <0.00%> (+0.19%) ⬆️
.../cloud/storage/benchmarks/throughput_experiment.cc 74.87% <0.00%> (+0.50%) ⬆️
...cloud/pubsub/internal/subscription_session_test.cc 98.50% <0.00%> (+0.74%) ⬆️
...e/cloud/spanner/testing/cleanup_stale_instances.cc 61.29% <0.00%> (+12.90%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 83656ab...8428356. Read the comment docs.

@google-cloud-cpp-bot
Copy link
Collaborator

Google Cloud Build Logs
For commit: 8428356c89a0b8bf484642149b677d6531013585

ℹ️ NOTE: Kokoro logs are linked from "Details" below.

@devjgm devjgm merged commit 38904d1 into googleapis:main Nov 13, 2021
devjgm added a commit to devjgm/google-cloud-cpp that referenced this pull request Nov 19, 2021
Similar to: googleapis#7588

This code allowed callers to (rightfully) move-out the `StatusOr` that
was held in `current_`. Therefore, it's a bug if we then consult the
status of `current_.ok()`, because it may be in a moved-from state.

The fix is to track the `current_ok_` bit separately, so that we only
ever assign to `current_` and never read it after it could have been
moved.
devjgm added a commit to devjgm/google-cloud-cpp that referenced this pull request Nov 19, 2021
Similar to: googleapis#7588

This code allowed callers to (rightfully) move-out the `StatusOr` that
was held in `current_`. Therefore, it's a bug if we then consult the
status of `current_.ok()`, because it may be in a moved-from state.

The fix is to track the `current_ok_` bit separately, so that we only
ever assign to `current_` and never read it after it could have been
moved.
devjgm added a commit that referenced this pull request Nov 19, 2021
Similar to: #7588

This code allowed callers to (rightfully) move-out the `StatusOr` that
was held in `current_`. Therefore, it's a bug if we then consult the
status of `current_.ok()`, because it may be in a moved-from state.

The fix is to track the `current_ok_` bit separately, so that we only
ever assign to `current_` and never read it after it could have been
moved.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: spanner Issues related to the Spanner API. cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants