From 425ac8d5203c4388edd2369c0bc4aa14cf3232f4 Mon Sep 17 00:00:00 2001 From: Jack May Date: Thu, 20 Jun 2019 19:09:50 -0700 Subject: [PATCH] Remove need to use null when passing Rust strings (#4756) --- programs/bpf_loader_api/src/lib.rs | 42 +++++++++++++++++++++++++++--- sdk/bpf/rust/rust-utils/src/log.rs | 13 ++------- 2 files changed, 40 insertions(+), 15 deletions(-) diff --git a/programs/bpf_loader_api/src/lib.rs b/programs/bpf_loader_api/src/lib.rs index 313ff6d94c..24366bfeb6 100644 --- a/programs/bpf_loader_api/src/lib.rs +++ b/programs/bpf_loader_api/src/lib.rs @@ -28,6 +28,8 @@ use std::ffi::CStr; use std::io::prelude::*; use std::io::{Error, ErrorKind}; use std::mem; +use std::slice::from_raw_parts; +use std::str::from_utf8; /// Program heap allocators are intended to allocate/free from a given /// chunk of memory. The specific allocator implementation is @@ -139,8 +141,7 @@ pub fn helper_sol_panic( } /// Logging helper functions, called when the BPF program calls `sol_log_()` or -/// `sol_log_64_()`. Both functions use a common verify function to validate -/// their parameters. +/// `sol_log_64_()`. pub fn helper_sol_log_verify( addr: u64, _arg2: u64, @@ -169,6 +170,39 @@ pub fn helper_sol_log( }; 0 } +pub fn helper_sol_log_verify_( + addr: u64, + len: u64, + _arg3: u64, + _arg4: u64, + _arg5: u64, + _context: &mut Option>, + ro_regions: &[MemoryRegion], + _rw_regions: &[MemoryRegion], +) -> Result<(()), Error> { + for region in ro_regions.iter() { + if region.addr <= addr && (addr as u64) + len <= region.addr + region.len { + return Ok(()); + } + } + Err(Error::new( + ErrorKind::Other, + "Error: Load segfault, bad string pointer", + )) +} +pub fn helper_sol_log_( + addr: u64, + len: u64, + _arg3: u64, + _arg4: u64, + _arg5: u64, + _context: &mut Option>, +) -> u64 { + let ptr: *const u8 = addr as *const u8; + let message = unsafe { from_utf8(from_raw_parts(ptr, len as usize)) }; + info!("sol_log: {:?}", message); + 0 +} pub fn helper_sol_log_u64( arg1: u64, arg2: u64, @@ -238,8 +272,8 @@ pub fn create_vm(prog: &[u8]) -> Result<(EbpfVmRaw, MemoryRegion), Error> { vm.register_helper_ex("sol_log", Some(helper_sol_log_verify), helper_sol_log, None)?; vm.register_helper_ex( "sol_log_", - Some(helper_sol_log_verify), - helper_sol_log, + Some(helper_sol_log_verify_), + helper_sol_log_, None, )?; vm.register_helper_ex("sol_log_64", None, helper_sol_log_u64, None)?; diff --git a/sdk/bpf/rust/rust-utils/src/log.rs b/sdk/bpf/rust/rust-utils/src/log.rs index 82b6d5558e..71315b9fc2 100644 --- a/sdk/bpf/rust/rust-utils/src/log.rs +++ b/sdk/bpf/rust/rust-utils/src/log.rs @@ -27,22 +27,13 @@ macro_rules! info { /// Prints a string to stdout /// /// @param message - Message to print -#[inline(never)] // prevent inline so everyone does not incur stack cost pub fn sol_log(message: &str) { - // Not pretty but 1/3 faster then using `clone_from_slice()` - let mut buf: [u8; 128] = [0; 128]; - for (i, b) in message.as_bytes().iter().enumerate() { - if i > 127 { - break; - } - buf[i] = *b; - } unsafe { - sol_log_(buf.as_ptr()); + sol_log_(message.as_ptr(), message.len() as u64); } } extern "C" { - fn sol_log_(message: *const u8); + fn sol_log_(message: *const u8, length: u64); } /// Prints 64 bit values represented as hexadecimal to stdout