Skip to content

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

Merged
seanyoung merged 1 commit intov2.1from
mergify/bp/v2.1/pr-4563
Jan 26, 2025
Merged

v2.1: Check account boundaries on overlapping memmove syscall (backport of #4563)#4598
seanyoung merged 1 commit intov2.1from
mergify/bp/v2.1/pr-4563

Conversation

@mergify
Copy link
Copy Markdown

@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
@mergify
Copy link
Copy Markdown
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
Copy Markdown

@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);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

get_or_insert_with()

Copy link
Copy Markdown

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
Copy Markdown

@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

}

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

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)

Copy link
Copy Markdown

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

Copy link
Copy Markdown

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(
Copy link
Copy Markdown

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?

Copy link
Copy Markdown

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

Copy link
Copy Markdown

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?

Copy link
Copy Markdown

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 {
Copy link
Copy Markdown

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 😅

Copy link
Copy Markdown

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
@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