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 native invoke writable privileges #19750

Merged
merged 2 commits into from
Sep 14, 2021

Conversation

jackcmay
Copy link
Contributor

@jackcmay jackcmay commented Sep 9, 2021

Problem

Caller write privileges are not created correctly for native cpi. The caller_write_privileges vector should match up with message.account_keys because they will be indexed the same.

Summary of Changes

  • Remove incorrect write privilege value insertion
  • Match up write privileges vector with the accounts vector built from message.account_keys

Fix sourced from: #18616, thanks @jstarry !

Fixes #18629

@jackcmay jackcmay force-pushed the fix-native=privs branch 2 times, most recently from 84c5619 to dabef09 Compare September 10, 2021 21:10
@jstarry
Copy link
Member

jstarry commented Sep 10, 2021

Looking now.. But first, can you also add a feature switch? There are two places where this will change behavior:

@jackcmay jackcmay requested a review from jstarry September 10, 2021 21:14
jstarry
jstarry previously approved these changes Sep 11, 2021
@mergify mergify bot dismissed jstarry’s stale review September 11, 2021 06:51

Pull request has been modified.

jstarry
jstarry previously approved these changes Sep 13, 2021
@mergify mergify bot dismissed jstarry’s stale review September 13, 2021 22:43

Pull request has been modified.

@codecov
Copy link

codecov bot commented Sep 14, 2021

Codecov Report

Merging #19750 (85fa41e) into master (36f870a) will decrease coverage by 0.0%.
The diff coverage is 88.4%.

@@            Coverage Diff            @@
##           master   #19750     +/-   ##
=========================================
- Coverage    82.5%    82.5%   -0.1%     
=========================================
  Files         476      476             
  Lines      132822   132964    +142     
=========================================
+ Hits       109708   109792     +84     
- Misses      23114    23172     +58     

@jackcmay jackcmay added the v1.7 label Sep 14, 2021
@jackcmay jackcmay merged commit 00d7981 into solana-labs:master Sep 14, 2021
@jackcmay jackcmay deleted the fix-native=privs branch September 14, 2021 05:57
mergify bot pushed a commit that referenced this pull request Sep 14, 2021
* Fix native invoke writable privileges

* build downstream spl bpf programs for tests

(cherry picked from commit 00d7981)

# Conflicts:
#	program-runtime/src/instruction_processor.rs
#	runtime/src/message_processor.rs
#	sdk/src/feature_set.rs
@Lichtso
Copy link
Contributor

Lichtso commented Sep 14, 2021

This all boils down to this, right?

let caller_keyed_accounts = invoke_context.get_keyed_accounts()?;
let mut caller_write_privileges = Vec::with_capacity(message.account_keys.len());
if invoke_context.is_feature_active(&fix_write_privs::id()) {
    for key in message.account_keys.iter() {
        let index = caller_keyed_accounts
            .iter()
            .position(|keyed_account| keyed_account.unsigned_key() == key)
            .ok_or(InstructionError::MissingAccount)?;
        caller_write_privileges.push(caller_keyed_accounts[index].is_writable());
    }
} else {
    caller_write_privileges.push(false);
    for index in keyed_account_indices.iter() {
        caller_write_privileges.push(caller_keyed_accounts[*index].is_writable());
    }
    // caller_write_privileges.insert(0, false);
}

And because message.account_keys is derived from caller_keyed_accounts and keyed_account_indices like this:

let callee_keyed_accounts = keyed_account_indices
    .iter()
    .map(|index| keyed_account_at_index(caller_keyed_accounts, *index))
    .collect::<Result<Vec<&KeyedAccount>, InstructionError>>()?;
let (message, callee_program_id, _) = Self::create_message(
    &instruction,
    &callee_keyed_accounts,
    signers,
    &invoke_context,
)?;

The only real difference remaining is the:
caller_write_privileges.push(false); or caller_write_privileges.insert(0, false); if fix_write_privs is off.

@jackcmay Do we have a test to highlight the difference? Because I have my doubts that this change actually changes anything (except for the first entry and thus everything being shifted by one).

@Lichtso
Copy link
Contributor

Lichtso commented Sep 14, 2021

Found the new test: message_processor::tests::test_native_invoke

And the flaw in my reasoning:
let message = Message::new(&[instruction.clone()], None);
The message.account_keys only depend on instruction not on the caller_keyed_accounts.

But then the question is: Why do we even pass keyed_account_indices into native_invoke only for it to possibly diverge?
Why not only derive keyed_account_indices_reordered from message.account_keys?
And aren't the callee_keyed_accounts possibly wrong as well?

@jackcmay
Copy link
Contributor Author

We may not need to pass keyed_account_indices, I'll take a look at that

@Lichtso
Copy link
Contributor

Lichtso commented Sep 14, 2021

Here, I refactored it already but still waiting for CI tests:
https://github.com/Lichtso/solana/tree/refactor/cpi_syscall_account_reuse

I think InstructionProcessor::create_message() could handle gathering the callee_keyed_accounts and caller_write_privileges both in the CPI syscall and in native_invoke.

@jackcmay
Copy link
Contributor Author

jackcmay commented Sep 14, 2021

That would be nice to consolidate

jackcmay added a commit that referenced this pull request Sep 15, 2021
* Fix native invoke writable privileges

* build downstream spl bpf programs for tests

(cherry picked from commit 00d7981)

# Conflicts:
#	program-runtime/src/instruction_processor.rs
#	runtime/src/message_processor.rs
#	sdk/src/feature_set.rs
jackcmay added a commit that referenced this pull request Sep 15, 2021
* Fix native invoke writable privileges

* build downstream spl bpf programs for tests

(cherry picked from commit 00d7981)

# Conflicts:
#	program-runtime/src/instruction_processor.rs
#	runtime/src/message_processor.rs
#	sdk/src/feature_set.rs
jackcmay added a commit that referenced this pull request Sep 15, 2021
* Fix native invoke writable privileges

* build downstream spl bpf programs for tests

(cherry picked from commit 00d7981)

# Conflicts:
#	program-runtime/src/instruction_processor.rs
#	runtime/src/message_processor.rs
#	sdk/src/feature_set.rs
mergify bot added a commit that referenced this pull request Sep 16, 2021
* Fix native invoke writable privileges (#19750)

* Fix native invoke writable privileges

* build downstream spl bpf programs for tests

(cherry picked from commit 00d7981)

# Conflicts:
#	program-runtime/src/instruction_processor.rs
#	runtime/src/message_processor.rs
#	sdk/src/feature_set.rs

* resolve conflictds

Co-authored-by: Jack May <[email protected]>
@Lichtso
Copy link
Contributor

Lichtso commented Sep 16, 2021

That would be nice to consolidate

Addressed in #19762

dankelleher pushed a commit to identity-com/solana that referenced this pull request Nov 24, 2021
* Fix native invoke writable privileges

* build downstream spl bpf programs for tests
frits-metalogix added a commit to identity-com/solana that referenced this pull request Nov 24, 2021
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.

Native CPI caller write privileges is incorrect
3 participants