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

v2.1: Check account boundaries on overlapping memmove syscall (backport of #4563) #4598

Merged
merged 1 commit into from
Jan 26, 2025

Conversation

mergify[bot]
Copy link

@mergify mergify bot commented Jan 23, 2025

Problem

Since SIMD-0219, any memmove cannot cross account data and non-account data boundaries. This was implemented in PR 3744.

However there was a check missing: memmove may do an overlapping copy which requires reverse iteration, and this code path did not have the check in place.

Summary of Changes

  • Add missing check and add tests
  • Since v2.1 is already on testnet, this needs a new feature
  • Feature can be folded into direct mapping feature in the future
  • Rekey direct mapping

Found by @yufeng-jump and @mjain-jump


This is an automatic backport of pull request #4563 done by [Mergify](https://mergify.com).

* fix reverse memmove

(cherry picked from commit 4b89b0f)
@mergify mergify bot requested a review from a team as a code owner January 23, 2025 15:21
Copy link
Author

mergify bot commented Jan 23, 2025

The Firedancer team maintains a line-for-line reimplementation of the
native programs, and until native programs are moved to BPF, those
implementations must exactly match their Agave counterparts.
If this PR represents a change to a native program implementation (not
tests), please include a reviewer from the Firedancer team. And please
keep refactors to a minimum.

@seanyoung seanyoung requested a review from Lichtso January 23, 2025 15:24
@alessandrod alessandrod self-requested a review January 24, 2025 22:41
Copy link

@t-nelson t-nelson left a comment

Choose a reason for hiding this comment

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

nit for master. fine as is

Comment on lines +559 to +562
let mut account_index = self
.account_index
.unwrap_or_else(|| self.accounts.len().saturating_sub(1));
self.account_index = Some(account_index);

Choose a reason for hiding this comment

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

get_or_insert_with()

Choose a reason for hiding this comment

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

You're right, this is nicer. Thanks! I'll create a PR on master

Copy link

@alessandrod alessandrod left a comment

Choose a reason for hiding this comment

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

I'm going to approve but i think we have missing coverage

@@ -108,7 +108,20 @@ pub fn process_instruction(
// memmov dst overlaps begin of account
unsafe { sol_memmove(too_early(3).as_mut_ptr(), buf.as_ptr(), 10) };
}

14 => {
// memmove dst overlaps begin of account, reverse order

Choose a reason for hiding this comment

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

my bad for not reviewing the master PR, but shouldn't these tests all test:

  • success in the boundary condition: dst=too_early(0), src=too_early(0)
  • failure at boundary-1: dst=too_early(0), src=too_early(1)
  • failure at boundary-N: dst=too_early(0), src=too_early(N)

Choose a reason for hiding this comment

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

I'll add tests on master

Choose a reason for hiding this comment

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

See #4650

15 => {
// memmove dst overlaps end of account, reverse order
unsafe {
sol_memmove(

Choose a reason for hiding this comment

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

which pointer here is causing the failure? I think they are both wrong? what
about the case where dst is ok but src is wrong? and vice versa?

Choose a reason for hiding this comment

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

the destination falls within src + length

Choose a reason for hiding this comment

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

data[data_len..].as_mut_ptr() + 10 <- isn't this outside the account region?

Choose a reason for hiding this comment

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

Sorry, I misread your comment. I've added a bunch of tests: #4650

.unwrap_or_else(|| self.accounts.len().saturating_sub(1));
self.account_index = Some(account_index);

loop {

Choose a reason for hiding this comment

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

This loop could use some comments, it took me half an hour to understand what
was going on 😅

Choose a reason for hiding this comment

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

That's true for a lot of runtime code. I'll review and add some comments

@seanyoung seanyoung merged commit 8ff524b into v2.1 Jan 26, 2025
29 checks passed
@seanyoung seanyoung deleted the mergify/bp/v2.1/pr-4563 branch January 26, 2025 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants