Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
Bail on all CPI errors (bp #14500) (#14506)
Browse files Browse the repository at this point in the history
* Bail on all CPI errors (#14500)

* Bail on all CPI errors

* whitespace

(cherry picked from commit ec48631)

* resolve conflicts

Co-authored-by: Jack May <[email protected]>
  • Loading branch information
mergify[bot] and jackcmay authored Jan 10, 2021
1 parent ac86d6e commit 6674025
Show file tree
Hide file tree
Showing 9 changed files with 132 additions and 97 deletions.
37 changes: 18 additions & 19 deletions programs/bpf/c/src/invoke/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ static const uint8_t TEST_CAP_SIGNERS = 7;
static const uint8_t TEST_ALLOC_ACCESS_VIOLATION = 8;
static const uint8_t TEST_INSTRUCTION_DATA_TOO_LARGE = 9;
static const uint8_t TEST_INSTRUCTION_META_TOO_LARGE = 10;
static const uint8_t TEST_RETURN_ERROR = 11;

static const int MINT_INDEX = 0;
static const int ARGUMENT_INDEX = 1;
Expand Down Expand Up @@ -112,7 +113,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
{accounts[INVOKED_ARGUMENT_INDEX].key, true, true},
{accounts[INVOKED_PROGRAM_INDEX].key, false, false},
{accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false}};
uint8_t data[] = {TEST_VERIFY_TRANSLATIONS, 1, 2, 3, 4, 5};
uint8_t data[] = {VERIFY_TRANSLATIONS, 1, 2, 3, 4, 5};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand All @@ -133,18 +134,6 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
}

sol_log("Test return error");
{
SolAccountMeta arguments[] = {{accounts[ARGUMENT_INDEX].key, true, true}};
uint8_t data[] = {TEST_RETURN_ERROR};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};

sol_assert(42 ==
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
}

sol_log("Test create_program_address");
{
uint8_t seed1[] = {'Y', 'o', 'u', ' ', 'p', 'a', 's', 's',
Expand Down Expand Up @@ -183,7 +172,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
{accounts[DERIVED_KEY1_INDEX].key, true, true},
{accounts[DERIVED_KEY2_INDEX].key, true, false},
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
uint8_t data[] = {TEST_DERIVED_SIGNERS, bump_seed2, bump_seed3};
uint8_t data[] = {DERIVED_SIGNERS, bump_seed2, bump_seed3};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand All @@ -202,7 +191,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
{
SolAccountMeta arguments[] = {
{accounts[INVOKED_ARGUMENT_INDEX].key, true, false}};
uint8_t data[] = {TEST_VERIFY_WRITER};
uint8_t data[] = {VERIFY_WRITER};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand All @@ -222,7 +211,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
{accounts[INVOKED_ARGUMENT_INDEX].key, true, true},
{accounts[ARGUMENT_INDEX].key, true, true},
{accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false}};
uint8_t data[] = {TEST_NESTED_INVOKE};
uint8_t data[] = {NESTED_INVOKE};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand Down Expand Up @@ -252,7 +241,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_log("Test privilege escalation signer");
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
uint8_t data[] = {TEST_VERIFY_PRIVILEGE_ESCALATION};
uint8_t data[] = {VERIFY_PRIVILEGE_ESCALATION};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand All @@ -268,7 +257,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_log("Test privilege escalation writable");
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
uint8_t data[] = {TEST_VERIFY_PRIVILEGE_ESCALATION};
uint8_t data[] = {VERIFY_PRIVILEGE_ESCALATION};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand All @@ -284,7 +273,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_log("Test program not executable");
SolAccountMeta arguments[] = {
{accounts[DERIVED_KEY3_INDEX].key, false, false}};
uint8_t data[] = {TEST_VERIFY_PRIVILEGE_ESCALATION};
uint8_t data[] = {VERIFY_PRIVILEGE_ESCALATION};
const SolInstruction instruction = {accounts[ARGUMENT_INDEX].key, arguments,
SOL_ARRAY_SIZE(arguments), data,
SOL_ARRAY_SIZE(data)};
Expand Down Expand Up @@ -437,6 +426,16 @@ extern uint64_t entrypoint(const uint8_t *input) {

break;
}
case TEST_RETURN_ERROR: {
SolAccountMeta arguments[] = {{accounts[ARGUMENT_INDEX].key, true, true}};
uint8_t data[] = {RETURN_ERROR};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};

sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts));
break;
}
default:
sol_panic();
}
Expand Down
15 changes: 8 additions & 7 deletions programs/bpf/c/src/invoked/instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@

#include <solana_sdk.h>

const uint8_t TEST_VERIFY_TRANSLATIONS = 0;
const uint8_t TEST_RETURN_ERROR = 1;
const uint8_t TEST_DERIVED_SIGNERS = 2;
const uint8_t TEST_VERIFY_NESTED_SIGNERS = 3;
const uint8_t TEST_VERIFY_WRITER = 4;
const uint8_t TEST_VERIFY_PRIVILEGE_ESCALATION = 5;
const uint8_t TEST_NESTED_INVOKE = 6;
const uint8_t VERIFY_TRANSLATIONS = 0;
const uint8_t RETURN_ERROR = 1;
const uint8_t DERIVED_SIGNERS = 2;
const uint8_t VERIFY_NESTED_SIGNERS = 3;
const uint8_t VERIFY_WRITER = 4;
const uint8_t VERIFY_PRIVILEGE_ESCALATION = 5;
const uint8_t NESTED_INVOKE = 6;
const uint8_t RETURN_OK = 7;
22 changes: 13 additions & 9 deletions programs/bpf/c/src/invoked/invoked.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
}

switch (params.data[0]) {
case TEST_VERIFY_TRANSLATIONS: {
case VERIFY_TRANSLATIONS: {
sol_log("verify data translations");

static const int ARGUMENT_INDEX = 0;
Expand Down Expand Up @@ -85,11 +85,15 @@ extern uint64_t entrypoint(const uint8_t *input) {
accounts[INVOKED_PROGRAM_DUP_INDEX].executable);
break;
}
case TEST_RETURN_ERROR: {
case RETURN_OK: {
sol_log("return Ok");
return SUCCESS;
}
case RETURN_ERROR: {
sol_log("return error");
return 42;
}
case TEST_DERIVED_SIGNERS: {
case DERIVED_SIGNERS: {
sol_log("verify derived signers");
static const int INVOKED_PROGRAM_INDEX = 0;
static const int DERIVED_KEY1_INDEX = 1;
Expand All @@ -108,7 +112,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
{accounts[DERIVED_KEY1_INDEX].key, true, false},
{accounts[DERIVED_KEY2_INDEX].key, true, true},
{accounts[DERIVED_KEY3_INDEX].key, false, true}};
uint8_t data[] = {TEST_VERIFY_NESTED_SIGNERS};
uint8_t data[] = {VERIFY_NESTED_SIGNERS};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand All @@ -130,7 +134,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
break;
}

case TEST_VERIFY_NESTED_SIGNERS: {
case VERIFY_NESTED_SIGNERS: {
sol_log("verify derived nested signers");
static const int DERIVED_KEY1_INDEX = 0;
static const int DERIVED_KEY2_INDEX = 1;
Expand All @@ -144,19 +148,19 @@ extern uint64_t entrypoint(const uint8_t *input) {
break;
}

case TEST_VERIFY_WRITER: {
case VERIFY_WRITER: {
sol_log("verify writable");
static const int ARGUMENT_INDEX = 0;
sol_assert(sol_deserialize(input, &params, 1));

sol_assert(accounts[ARGUMENT_INDEX].is_writable);
break;
}
case TEST_VERIFY_PRIVILEGE_ESCALATION: {
case VERIFY_PRIVILEGE_ESCALATION: {
sol_log("Success");
break;
}
case TEST_NESTED_INVOKE: {
case NESTED_INVOKE: {
sol_log("invoke");

static const int INVOKED_ARGUMENT_INDEX = 0;
Expand All @@ -179,7 +183,7 @@ extern uint64_t entrypoint(const uint8_t *input) {
SolAccountMeta arguments[] = {
{accounts[INVOKED_ARGUMENT_INDEX].key, true, true},
{accounts[ARGUMENT_INDEX].key, true, true}};
uint8_t data[] = {TEST_NESTED_INVOKE};
uint8_t data[] = {NESTED_INVOKE};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};
Expand Down
54 changes: 21 additions & 33 deletions programs/bpf/rust/invoke/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const TEST_CAP_SIGNERS: u8 = 7;
const TEST_ALLOC_ACCESS_VIOLATION: u8 = 8;
const TEST_INSTRUCTION_DATA_TOO_LARGE: u8 = 9;
const TEST_INSTRUCTION_META_TOO_LARGE: u8 = 10;
const TEST_RETURN_ERROR: u8 = 11;

// const MINT_INDEX: usize = 0;
const ARGUMENT_INDEX: usize = 1;
Expand Down Expand Up @@ -122,7 +123,7 @@ fn process_instruction(
(accounts[INVOKED_PROGRAM_INDEX].key, false, false),
(accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false),
],
vec![TEST_VERIFY_TRANSLATIONS, 1, 2, 3, 4, 5],
vec![VERIFY_TRANSLATIONS, 1, 2, 3, 4, 5],
);
invoke(&instruction, accounts)?;
}
Expand All @@ -137,19 +138,6 @@ fn process_instruction(
invoke(&instruction, accounts)?;
}

msg!("Test return error");
{
let instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[(accounts[ARGUMENT_INDEX].key, true, true)],
vec![TEST_RETURN_ERROR],
);
assert_eq!(
invoke(&instruction, accounts),
Err(ProgramError::Custom(42))
);
}

msg!("Test refcell usage");
{
let writable = INVOKED_ARGUMENT_INDEX;
Expand All @@ -161,14 +149,11 @@ fn process_instruction(
(accounts[writable].key, true, true),
(accounts[readable].key, false, false),
],
vec![TEST_RETURN_ERROR, 1, 2, 3, 4, 5],
vec![RETURN_OK, 1, 2, 3, 4, 5],
);

// success with this account configuration as a check
assert_eq!(
invoke(&instruction, accounts),
Err(ProgramError::Custom(42))
);
invoke(&instruction, accounts)?;

{
// writable but lamports borrow_mut'd
Expand Down Expand Up @@ -221,18 +206,12 @@ fn process_instruction(
{
// readable but lamports borrow'd
let _ref_mut = accounts[readable].try_borrow_lamports()?;
assert_eq!(
invoke(&instruction, accounts),
Err(ProgramError::Custom(42))
);
invoke(&instruction, accounts)?;
}
{
// readable but data borrow'd
let _ref_mut = accounts[readable].try_borrow_data()?;
assert_eq!(
invoke(&instruction, accounts),
Err(ProgramError::Custom(42))
);
invoke(&instruction, accounts)?;
}
}

Expand Down Expand Up @@ -279,7 +258,7 @@ fn process_instruction(
(accounts[DERIVED_KEY2_INDEX].key, true, false),
(accounts[DERIVED_KEY3_INDEX].key, false, false),
],
vec![TEST_DERIVED_SIGNERS, bump_seed2, bump_seed3],
vec![DERIVED_SIGNERS, bump_seed2, bump_seed3],
);
invoke_signed(
&invoked_instruction,
Expand All @@ -293,7 +272,7 @@ fn process_instruction(
let invoked_instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[(accounts[ARGUMENT_INDEX].key, false, true)],
vec![TEST_VERIFY_WRITER],
vec![VERIFY_WRITER],
);
invoke(&invoked_instruction, accounts)?;
}
Expand All @@ -314,7 +293,7 @@ fn process_instruction(
(accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false),
(accounts[INVOKED_PROGRAM_DUP_INDEX].key, false, false),
],
vec![TEST_NESTED_INVOKE],
vec![NESTED_INVOKE],
);
invoke(&instruction, accounts)?;
msg!("2nd invoke from first program");
Expand Down Expand Up @@ -344,7 +323,7 @@ fn process_instruction(
let mut invoked_instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[(accounts[DERIVED_KEY3_INDEX].key, false, false)],
vec![TEST_VERIFY_PRIVILEGE_ESCALATION],
vec![VERIFY_PRIVILEGE_ESCALATION],
);
invoke(&invoked_instruction, accounts)?;

Expand All @@ -357,7 +336,7 @@ fn process_instruction(
let mut invoked_instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[(accounts[DERIVED_KEY3_INDEX].key, false, false)],
vec![TEST_VERIFY_PRIVILEGE_ESCALATION],
vec![VERIFY_PRIVILEGE_ESCALATION],
);
invoke(&invoked_instruction, accounts)?;

Expand All @@ -371,7 +350,7 @@ fn process_instruction(
let instruction = create_instruction(
*accounts[ARGUMENT_INDEX].key,
&[(accounts[ARGUMENT_INDEX].key, true, true)],
vec![TEST_RETURN_ERROR],
vec![RETURN_OK],
);
invoke(&instruction, accounts)?;
}
Expand Down Expand Up @@ -504,6 +483,15 @@ fn process_instruction(
);
invoke_signed(&instruction, &[], &[])?;
}
TEST_RETURN_ERROR => {
msg!("Test return error");
let instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[(accounts[INVOKED_ARGUMENT_INDEX].key, false, true)],
vec![RETURN_ERROR],
);
let _ = invoke(&instruction, accounts);
}
_ => panic!(),
}

Expand Down
15 changes: 8 additions & 7 deletions programs/bpf/rust/invoked/src/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ use solana_program::{
pubkey::Pubkey,
};

pub const TEST_VERIFY_TRANSLATIONS: u8 = 0;
pub const TEST_RETURN_ERROR: u8 = 1;
pub const TEST_DERIVED_SIGNERS: u8 = 2;
pub const TEST_VERIFY_NESTED_SIGNERS: u8 = 3;
pub const TEST_VERIFY_WRITER: u8 = 4;
pub const TEST_VERIFY_PRIVILEGE_ESCALATION: u8 = 5;
pub const TEST_NESTED_INVOKE: u8 = 6;
pub const VERIFY_TRANSLATIONS: u8 = 0;
pub const RETURN_ERROR: u8 = 1;
pub const DERIVED_SIGNERS: u8 = 2;
pub const VERIFY_NESTED_SIGNERS: u8 = 3;
pub const VERIFY_WRITER: u8 = 4;
pub const VERIFY_PRIVILEGE_ESCALATION: u8 = 5;
pub const NESTED_INVOKE: u8 = 6;
pub const RETURN_OK: u8 = 7;

pub fn create_instruction(
program_id: Pubkey,
Expand Down
Loading

0 comments on commit 6674025

Please sign in to comment.