Fix BPF parameter alignment to work regardless of target ABI (#21271)

This commit is contained in:
Ben Newhouse 2021-11-16 10:02:22 -05:00 committed by GitHub
parent 72d7e426a6
commit 7e600bd451
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 19 deletions

View File

@ -199,21 +199,20 @@ encoding is little endian):
- 1 byte indicating if this is a duplicate account, if not a duplicate then - 1 byte indicating if this is a duplicate account, if not a duplicate then
the value is 0xff, otherwise the value is the index of the account it is a the value is 0xff, otherwise the value is the index of the account it is a
duplicate of. duplicate of.
- 7 bytes of padding - If duplicate: 7 bytes of padding
- if not duplicate - If not duplicate:
- 1 byte padding - 1 byte boolean, true if account is a signer
- 1 byte boolean, true if account is a signer - 1 byte boolean, true if account is writable
- 1 byte boolean, true if account is writable - 1 byte boolean, true if account is executable
- 1 byte boolean, true if account is executable - 4 bytes of padding
- 4 bytes of padding - 32 bytes of the account public key
- 32 bytes of the account public key - 32 bytes of the account's owner public key
- 32 bytes of the account's owner public key - 8 byte unsigned number of lamports owned by the account
- 8 byte unsigned number of lamports owned by the account - 8 bytes unsigned number of bytes of account data
- 8 bytes unsigned number of bytes of account data - x bytes of account data
- x bytes of account data - 10k bytes of padding, used for realloc
- 10k bytes of padding, used for realloc - enough padding to align the offset to 8 bytes.
- enough padding to align the offset to 8 bytes. - 8 bytes rent epoch
- 8 bytes rent epoch
- 8 bytes of unsigned number of instruction data - 8 bytes of unsigned number of instruction data
- x bytes of instruction data - x bytes of instruction data
- 32 bytes of the program id - 32 bytes of the program id

View File

@ -3,7 +3,7 @@ use solana_rbpf::{aligned_memory::AlignedMemory, ebpf::HOST_ALIGN};
use solana_sdk::{ use solana_sdk::{
account::{ReadableAccount, WritableAccount}, account::{ReadableAccount, WritableAccount},
bpf_loader_deprecated, bpf_loader_deprecated,
entrypoint::MAX_PERMITTED_DATA_INCREASE, entrypoint::{MAX_PERMITTED_DATA_INCREASE, PARAMETER_ALIGNMENT},
instruction::InstructionError, instruction::InstructionError,
keyed_account::KeyedAccount, keyed_account::KeyedAccount,
pubkey::Pubkey, pubkey::Pubkey,
@ -242,7 +242,7 @@ pub fn serialize_parameters_aligned(
.map_err(|_| InstructionError::InvalidArgument)?; .map_err(|_| InstructionError::InvalidArgument)?;
v.resize( v.resize(
MAX_PERMITTED_DATA_INCREASE MAX_PERMITTED_DATA_INCREASE
+ (v.write_index() as *const u8).align_offset(align_of::<u128>()), + (v.write_index() as *const u8).align_offset(PARAMETER_ALIGNMENT),
0, 0,
) )
.map_err(|_| InstructionError::InvalidArgument)?; .map_err(|_| InstructionError::InvalidArgument)?;

View File

@ -7,7 +7,7 @@ use alloc::vec::Vec;
use std::{ use std::{
alloc::Layout, alloc::Layout,
cell::RefCell, cell::RefCell,
mem::{align_of, size_of}, mem::size_of,
ptr::null_mut, ptr::null_mut,
rc::Rc, rc::Rc,
// Hide Result from bindgen gets confused about generics in non-generic type declarations // Hide Result from bindgen gets confused about generics in non-generic type declarations
@ -252,6 +252,9 @@ unsafe impl std::alloc::GlobalAlloc for BumpAllocator {
/// Maximum number of bytes a program may add to an account during a single realloc /// 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; 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;
/// Deserialize the input arguments /// Deserialize the input arguments
/// ///
/// The integer arithmetic in this method is safe when called on a buffer that was /// The integer arithmetic in this method is safe when called on a buffer that was
@ -309,7 +312,7 @@ pub unsafe fn deserialize<'a>(input: *mut u8) -> (&'a Pubkey, Vec<AccountInfo<'a
from_raw_parts_mut(input.add(offset), data_len) from_raw_parts_mut(input.add(offset), data_len)
})); }));
offset += data_len + MAX_PERMITTED_DATA_INCREASE; offset += data_len + MAX_PERMITTED_DATA_INCREASE;
offset += (offset as *const u8).align_offset(align_of::<u128>()); // padding offset += (offset as *const u8).align_offset(PARAMETER_ALIGNMENT); // padding
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
let rent_epoch = *(input.add(offset) as *const u64); let rent_epoch = *(input.add(offset) as *const u64);