diff --git a/ci/test-checks.sh b/ci/test-checks.sh index f58eaa473da3e5..6ffdf134746bc7 100755 --- a/ci/test-checks.sh +++ b/ci/test-checks.sh @@ -57,26 +57,20 @@ if [[ $CI_BASE_BRANCH = "$EDGE_CHANNEL" ]]; then exit "$check_status" fi - # Ensure nightly and --benches + # Ensure nightly and --benches _ scripts/cargo-for-all-lock-files.sh nightly check --locked --all-targets else echo "Note: cargo-for-all-lock-files.sh skipped because $CI_BASE_BRANCH != $EDGE_CHANNEL" fi -_ ci/order-crates-for-publishing.py + _ ci/order-crates-for-publishing.py # -Z... is needed because of clippy bug: https://github.com/rust-lang/rust-clippy/issues/4612 # run nightly clippy for `sdk/` as there's a moderate amount of nightly-only code there -_ "$cargo" nightly clippy -Zunstable-options --workspace --all-targets -- --deny=warnings --deny=clippy::integer_arithmetic + _ scripts/cargo-for-all-lock-files.sh -- nightly clippy -Zunstable-options --all-targets -- --deny=warnings --deny=clippy::integer_arithmetic -_ "$cargo" nightly fmt --all -- --check +_ scripts/cargo-for-all-lock-files.sh -- nightly fmt --all -- --check -_ ci/do-audit.sh - -{ - cd programs/bpf - _ "$cargo" nightly clippy --all -- --deny=warnings --allow=clippy::missing_safety_doc - _ "$cargo" nightly fmt --all -- --check -} + _ ci/do-audit.sh echo --- ok diff --git a/programs/bpf/build.rs b/programs/bpf/build.rs index 517f0a2157e6cb..30bef9df1ee189 100644 --- a/programs/bpf/build.rs +++ b/programs/bpf/build.rs @@ -39,8 +39,7 @@ fn rerun_if_changed(files: &[&str], directories: &[&str], excludes: &[&str]) { fn main() { let bpf_c = env::var("CARGO_FEATURE_BPF_C").is_ok(); if bpf_c { - let install_dir = - "OUT_DIR=../target/".to_string() + &env::var("PROFILE").unwrap() + &"/bpf".to_string(); + let install_dir = "OUT_DIR=../target/".to_string() + &env::var("PROFILE").unwrap() + "/bpf"; println!("cargo:warning=(not a warning) Building C-based BPF programs"); assert!(Command::new("make") @@ -56,8 +55,7 @@ fn main() { let bpf_rust = env::var("CARGO_FEATURE_BPF_RUST").is_ok(); if bpf_rust { - let install_dir = - "target/".to_string() + &env::var("PROFILE").unwrap() + &"/bpf".to_string(); + let install_dir = "target/".to_string() + &env::var("PROFILE").unwrap() + "/bpf"; let rust_programs = [ "128bit", diff --git a/programs/bpf/rust/invoke/src/processor.rs b/programs/bpf/rust/invoke/src/processor.rs index 5c3503e25392a5..9100bfa357829b 100644 --- a/programs/bpf/rust/invoke/src/processor.rs +++ b/programs/bpf/rust/invoke/src/processor.rs @@ -23,8 +23,12 @@ fn do_nested_invokes(num_nested_invokes: u64, accounts: &[AccountInfo]) -> Progr let pre_argument_lamports = accounts[ARGUMENT_INDEX].lamports(); let pre_invoke_argument_lamports = accounts[INVOKED_ARGUMENT_INDEX].lamports(); - **accounts[ARGUMENT_INDEX].lamports.borrow_mut() -= 5; - **accounts[INVOKED_ARGUMENT_INDEX].lamports.borrow_mut() += 5; + { + let mut lamports = (*accounts[ARGUMENT_INDEX].lamports).borrow_mut(); + **lamports = (*lamports).saturating_sub(5); + let mut lamports = (*accounts[INVOKED_ARGUMENT_INDEX].lamports).borrow_mut(); + **lamports = (*lamports).saturating_add(5); + } msg!("First invoke"); let instruction = create_instruction( @@ -42,11 +46,15 @@ fn do_nested_invokes(num_nested_invokes: u64, accounts: &[AccountInfo]) -> Progr assert_eq!( accounts[ARGUMENT_INDEX].lamports(), - pre_argument_lamports - 5 + (2 * num_nested_invokes) + pre_argument_lamports + .saturating_sub(5) + .saturating_add(2_u64.saturating_mul(num_nested_invokes)) ); assert_eq!( accounts[INVOKED_ARGUMENT_INDEX].lamports(), - pre_invoke_argument_lamports + 5 - (2 * num_nested_invokes) + pre_invoke_argument_lamports + .saturating_add(5) + .saturating_sub(2_u64.saturating_mul(num_nested_invokes)) ); Ok(()) } @@ -87,17 +95,23 @@ fn process_instruction( &[&[b"You pass butter", &[bump_seed1]]], )?; - assert_eq!(accounts[FROM_INDEX].lamports(), from_lamports - 42); - assert_eq!(accounts[DERIVED_KEY1_INDEX].lamports(), to_lamports + 42); + assert_eq!( + accounts[FROM_INDEX].lamports(), + from_lamports.saturating_sub(42) + ); + assert_eq!( + accounts[DERIVED_KEY1_INDEX].lamports(), + to_lamports.saturating_add(42) + ); assert_eq!(program_id, accounts[DERIVED_KEY1_INDEX].owner); assert_eq!( accounts[DERIVED_KEY1_INDEX].data_len(), MAX_PERMITTED_DATA_INCREASE ); let mut data = accounts[DERIVED_KEY1_INDEX].try_borrow_mut_data()?; - assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0); - data[MAX_PERMITTED_DATA_INCREASE - 1] = 0x0f; - assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0x0f); + assert_eq!(data[MAX_PERMITTED_DATA_INCREASE.saturating_sub(1)], 0); + data[MAX_PERMITTED_DATA_INCREASE.saturating_sub(1)] = 0x0f; + assert_eq!(data[MAX_PERMITTED_DATA_INCREASE.saturating_sub(1)], 0x0f); for i in 0..20 { data[i] = i as u8; } @@ -113,8 +127,14 @@ fn process_instruction( 1, ); invoke(&instruction, accounts)?; - assert_eq!(accounts[FROM_INDEX].lamports(), from_lamports - 1); - assert_eq!(accounts[DERIVED_KEY1_INDEX].lamports(), to_lamports + 1); + assert_eq!( + accounts[FROM_INDEX].lamports(), + from_lamports.saturating_sub(1) + ); + assert_eq!( + accounts[DERIVED_KEY1_INDEX].lamports(), + to_lamports.saturating_add(1) + ); } msg!("Test data translation"); @@ -357,11 +377,17 @@ fn process_instruction( ); invoke(&instruction, accounts)?; - assert_eq!(accounts[FROM_INDEX].lamports(), from_lamports - 1); - assert_eq!(accounts[DERIVED_KEY2_INDEX].lamports(), to_lamports + 1); + assert_eq!( + accounts[FROM_INDEX].lamports(), + from_lamports.saturating_sub(1) + ); + assert_eq!( + accounts[DERIVED_KEY2_INDEX].lamports(), + to_lamports.saturating_add(1) + ); let data = accounts[DERIVED_KEY2_INDEX].try_borrow_mut_data()?; assert_eq!(data[0], 0x0e); - assert_eq!(data[MAX_PERMITTED_DATA_INCREASE - 1], 0x0f); + assert_eq!(data[MAX_PERMITTED_DATA_INCREASE.saturating_sub(1)], 0x0f); for i in 1..20 { assert_eq!(data[i], i as u8); } @@ -608,9 +634,15 @@ fn process_instruction( // set account to executable and subtract lamports accounts[ARGUMENT_INDEX].executable = true; - **(*accounts[ARGUMENT_INDEX].lamports).borrow_mut() -= 1; + { + let mut lamports = (*accounts[ARGUMENT_INDEX].lamports).borrow_mut(); + **lamports = (*lamports).saturating_sub(1); + } // add lamports to dest account - **(*accounts[DERIVED_KEY1_INDEX].lamports).borrow_mut() += 1; + { + let mut lamports = (*accounts[DERIVED_KEY1_INDEX].lamports).borrow_mut(); + **lamports = (*lamports).saturating_add(1); + } let instruction = create_instruction( *program_id, @@ -623,7 +655,10 @@ fn process_instruction( let _ = invoke(&instruction, &accounts); // reset executable account - **(*accounts[ARGUMENT_INDEX].lamports).borrow_mut() += 1; + { + let mut lamports = (*accounts[ARGUMENT_INDEX].lamports).borrow_mut(); + **lamports = (*lamports).saturating_add(1); + } } TEST_CALL_PRECOMPILE => { msg!("Test calling precompiled program from cpi"); @@ -633,7 +668,10 @@ fn process_instruction( } ADD_LAMPORTS => { // make sure the total balance is fine - **accounts[0].lamports.borrow_mut() += 1; + { + let mut lamports = (*accounts[0].lamports).borrow_mut(); + **lamports = (*lamports).saturating_add(1); + } } TEST_RETURN_DATA_TOO_LARGE => { set_return_data(&[1u8; 1028]); diff --git a/programs/bpf/rust/realloc/src/instructions.rs b/programs/bpf/rust/realloc/src/instructions.rs index 58ba925da6b1b2..ed8f4e52c35b66 100644 --- a/programs/bpf/rust/realloc/src/instructions.rs +++ b/programs/bpf/rust/realloc/src/instructions.rs @@ -19,7 +19,7 @@ pub fn realloc(program_id: &Pubkey, address: &Pubkey, size: usize, bump: &mut u8 let mut instruction_data = vec![REALLOC, *bump]; instruction_data.extend_from_slice(&size.to_le_bytes()); - *bump += 1; + *bump = bump.saturating_add(1); Instruction::new_with_bytes( *program_id, @@ -37,7 +37,7 @@ pub fn realloc_extend( let mut instruction_data = vec![REALLOC_EXTEND, *bump]; instruction_data.extend_from_slice(&size.to_le_bytes()); - *bump += 1; + *bump = bump.saturating_add(1); Instruction::new_with_bytes( *program_id, @@ -61,7 +61,7 @@ pub fn realloc_extend_and_fill( ]; instruction_data.extend_from_slice(&size.to_le_bytes()); - *bump += 1; + *bump = bump.saturating_add(1); Instruction::new_with_bytes( *program_id, diff --git a/programs/bpf/rust/realloc/src/processor.rs b/programs/bpf/rust/realloc/src/processor.rs index 8e16b776d4ad06..63d35ba3a8234f 100644 --- a/programs/bpf/rust/realloc/src/processor.rs +++ b/programs/bpf/rust/realloc/src/processor.rs @@ -36,7 +36,7 @@ fn process_instruction( REALLOC_EXTEND => { let pre_len = account.data_len(); let (bytes, _) = instruction_data[2..].split_at(std::mem::size_of::()); - let new_len = pre_len + usize::from_le_bytes(bytes.try_into().unwrap()); + let new_len = pre_len.saturating_add(usize::from_le_bytes(bytes.try_into().unwrap())); msg!("realloc extend by {}", new_len); account.realloc(new_len, false)?; assert_eq!(new_len, account.data_len()); @@ -45,7 +45,7 @@ fn process_instruction( let pre_len = account.data_len(); let fill = instruction_data[2]; let (bytes, _) = instruction_data[4..].split_at(std::mem::size_of::()); - let new_len = pre_len + usize::from_le_bytes(bytes.try_into().unwrap()); + let new_len = pre_len.saturating_add(usize::from_le_bytes(bytes.try_into().unwrap())); msg!("realloc extend by {}", new_len); account.realloc(new_len, false)?; assert_eq!(new_len, account.data_len()); @@ -61,8 +61,11 @@ fn process_instruction( REALLOC_AND_ASSIGN_TO_SELF_VIA_SYSTEM_PROGRAM => { msg!("realloc and assign to self via system program"); let pre_len = account.data_len(); - account.realloc(pre_len + MAX_PERMITTED_DATA_INCREASE, false)?; - assert_eq!(pre_len + MAX_PERMITTED_DATA_INCREASE, account.data_len()); + account.realloc(pre_len.saturating_add(MAX_PERMITTED_DATA_INCREASE), false)?; + assert_eq!( + pre_len.saturating_add(MAX_PERMITTED_DATA_INCREASE), + account.data_len() + ); invoke( &system_instruction::assign(account.key, program_id), accounts, @@ -77,8 +80,11 @@ fn process_instruction( accounts, )?; assert_eq!(account.owner, program_id); - account.realloc(pre_len + MAX_PERMITTED_DATA_INCREASE, false)?; - assert_eq!(account.data_len(), pre_len + MAX_PERMITTED_DATA_INCREASE); + account.realloc(pre_len.saturating_add(MAX_PERMITTED_DATA_INCREASE), false)?; + assert_eq!( + account.data_len(), + pre_len.saturating_add(MAX_PERMITTED_DATA_INCREASE) + ); } DEALLOC_AND_ASSIGN_TO_CALLER => { msg!("dealloc and assign to caller"); diff --git a/programs/bpf/rust/realloc_invoke/src/processor.rs b/programs/bpf/rust/realloc_invoke/src/processor.rs index 64a504439bc610..044b95e2a9354d 100644 --- a/programs/bpf/rust/realloc_invoke/src/processor.rs +++ b/programs/bpf/rust/realloc_invoke/src/processor.rs @@ -52,7 +52,7 @@ fn process_instruction( &realloc( invoke_program_id, account.key, - MAX_PERMITTED_DATA_INCREASE + 1, + MAX_PERMITTED_DATA_INCREASE.saturating_add(1), &mut bump, ), accounts, @@ -69,7 +69,10 @@ fn process_instruction( ), accounts, )?; - assert_eq!(pre_len + MAX_PERMITTED_DATA_INCREASE, account.data_len()); + assert_eq!( + pre_len.saturating_add(MAX_PERMITTED_DATA_INCREASE), + account.data_len() + ); } INVOKE_REALLOC_MAX_TWICE => { msg!("invoke realloc max twice"); @@ -82,10 +85,13 @@ fn process_instruction( ), accounts, )?; - let new_len = pre_len + MAX_PERMITTED_DATA_INCREASE; + let new_len = pre_len.saturating_add(MAX_PERMITTED_DATA_INCREASE); assert_eq!(new_len, account.data_len()); - account.realloc(new_len + MAX_PERMITTED_DATA_INCREASE, false)?; - assert_eq!(new_len + MAX_PERMITTED_DATA_INCREASE, account.data_len()); + account.realloc(new_len.saturating_add(MAX_PERMITTED_DATA_INCREASE), false)?; + assert_eq!( + new_len.saturating_add(MAX_PERMITTED_DATA_INCREASE), + account.data_len() + ); } INVOKE_REALLOC_AND_ASSIGN => { msg!("invoke realloc and assign"); @@ -97,7 +103,10 @@ fn process_instruction( ), accounts, )?; - assert_eq!(pre_len + MAX_PERMITTED_DATA_INCREASE, account.data_len()); + assert_eq!( + pre_len.saturating_add(MAX_PERMITTED_DATA_INCREASE), + account.data_len() + ); assert_eq!(*account.owner, system_program::id()); } INVOKE_REALLOC_AND_ASSIGN_TO_SELF_VIA_SYSTEM_PROGRAM => { @@ -197,8 +206,8 @@ fn process_instruction( accounts, )?; assert_eq!(pre_len, accounts[1].data_len()); - accounts[1].realloc(pre_len + 1, false)?; - assert_eq!(pre_len + 1, accounts[1].data_len()); + accounts[1].realloc(pre_len.saturating_add(1), false)?; + assert_eq!(pre_len.saturating_add(1), accounts[1].data_len()); assert_eq!(accounts[1].owner, program_id); let final_len: usize = 200; let mut new_instruction_data = vec![]; @@ -221,7 +230,7 @@ fn process_instruction( msg!("realloc zerod"); let (bytes, _) = instruction_data[2..].split_at(std::mem::size_of::()); let pre_len = usize::from_le_bytes(bytes.try_into().unwrap()); - let new_len = pre_len * 2; + let new_len = pre_len.saturating_mul(2); assert_eq!(pre_len, 100); { let data = account.try_borrow_mut_data()?;