From 098dba607ace19fb5dcb5bddc12823b0bb4777f6 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Tue, 30 Nov 2021 10:41:15 -0800 Subject: [PATCH] Fix more BPF alignment issues on arm64 --- programs/bpf_loader/src/serialization.rs | 19 ++++++++----------- programs/bpf_loader/src/syscalls.rs | 4 ++-- sdk/program/src/entrypoint.rs | 6 +++--- 3 files changed, 13 insertions(+), 16 deletions(-) diff --git a/programs/bpf_loader/src/serialization.rs b/programs/bpf_loader/src/serialization.rs index d9aeae6302..86cb5b9844 100644 --- a/programs/bpf_loader/src/serialization.rs +++ b/programs/bpf_loader/src/serialization.rs @@ -3,16 +3,13 @@ use solana_rbpf::{aligned_memory::AlignedMemory, ebpf::HOST_ALIGN}; use solana_sdk::{ account::{ReadableAccount, WritableAccount}, bpf_loader_deprecated, - entrypoint::{MAX_PERMITTED_DATA_INCREASE, PARAMETER_ALIGNMENT}, + entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE}, instruction::InstructionError, keyed_account::KeyedAccount, pubkey::Pubkey, system_instruction::MAX_PERMITTED_DATA_LENGTH, }; -use std::{ - io::prelude::*, - mem::{align_of, size_of}, -}; +use std::{io::prelude::*, mem::size_of}; /// Look for a duplicate account and return its position if found pub fn is_dup(accounts: &[KeyedAccount], keyed_account: &KeyedAccount) -> (bool, usize) { @@ -183,7 +180,7 @@ pub fn get_serialized_account_size_aligned( + size_of::() // data len + data_len + MAX_PERMITTED_DATA_INCREASE - + (data_len as *const u8).align_offset(align_of::()) + + (data_len as *const u8).align_offset(BPF_ALIGN_OF_U128) + size_of::(), // rent epoch ) } @@ -242,7 +239,7 @@ pub fn serialize_parameters_aligned( .map_err(|_| InstructionError::InvalidArgument)?; v.resize( MAX_PERMITTED_DATA_INCREASE - + (v.write_index() as *const u8).align_offset(PARAMETER_ALIGNMENT), + + (v.write_index() as *const u8).align_offset(BPF_ALIGN_OF_U128), 0, ) .map_err(|_| InstructionError::InvalidArgument)?; @@ -306,7 +303,7 @@ pub fn deserialize_parameters_aligned( }; account.set_data_from_slice(&buffer[start..data_end]); start += *pre_len + MAX_PERMITTED_DATA_INCREASE; // data - start += (start as *const u8).align_offset(align_of::()); + start += (start as *const u8).align_offset(BPF_ALIGN_OF_U128); start += size_of::(); // rent_epoch } } @@ -478,7 +475,7 @@ mod tests { assert_eq!(&program_id, de_program_id); assert_eq!(instruction_data, de_instruction_data); assert_eq!( - (&de_instruction_data[0] as *const u8).align_offset(align_of::()), + (&de_instruction_data[0] as *const u8).align_offset(BPF_ALIGN_OF_U128), 0 ); for ((_, _, key, account), account_info) in keyed_accounts.iter().skip(1).zip(de_accounts) { @@ -491,7 +488,7 @@ mod tests { assert_eq!(account.rent_epoch(), account_info.rent_epoch); assert_eq!( - (*account_info.lamports.borrow() as *const u64).align_offset(align_of::()), + (*account_info.lamports.borrow() as *const u64).align_offset(BPF_ALIGN_OF_U128), 0 ); assert_eq!( @@ -499,7 +496,7 @@ mod tests { .data .borrow() .as_ptr() - .align_offset(align_of::()), + .align_offset(BPF_ALIGN_OF_U128), 0 ); } diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index d05ba9732a..33c63f04f1 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -22,7 +22,7 @@ use solana_sdk::{ account_info::AccountInfo, blake3, bpf_loader, bpf_loader_deprecated, bpf_loader_upgradeable, clock::Clock, - entrypoint::{MAX_PERMITTED_DATA_INCREASE, SUCCESS}, + entrypoint::{BPF_ALIGN_OF_U128, MAX_PERMITTED_DATA_INCREASE, SUCCESS}, epoch_schedule::EpochSchedule, feature_set::{ blake3_syscall_enabled, demote_program_write_locks, disable_fees_sysvar, @@ -747,7 +747,7 @@ impl SyscallObject for SyscallAllocFree { result: &mut Result>, ) { let align = if self.aligned { - align_of::() + BPF_ALIGN_OF_U128 } else { align_of::() }; diff --git a/sdk/program/src/entrypoint.rs b/sdk/program/src/entrypoint.rs index 317f0665fe..6442ac9246 100644 --- a/sdk/program/src/entrypoint.rs +++ b/sdk/program/src/entrypoint.rs @@ -252,8 +252,8 @@ unsafe impl std::alloc::GlobalAlloc for BumpAllocator { /// Maximum number of bytes a program may add to an account during a single realloc pub const MAX_PERMITTED_DATA_INCREASE: usize = 1_024 * 10; -// Parameters passed to the entrypoint input buffer are aligned on 8-byte boundaries -pub const PARAMETER_ALIGNMENT: usize = 8; +/// `assert_eq(std::mem::align_of::(), 8)` is true for BPF but not for some host machines +pub const BPF_ALIGN_OF_U128: usize = 8; /// Deserialize the input arguments /// @@ -312,7 +312,7 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec