Skip to content

Commit

Permalink
backport: Only check pointer if length is non-zero
Browse files Browse the repository at this point in the history
This is a backport of #2137

A pointer is allowed to be any undefined value if the original slice's
length is 0.

See: rust-lang/rust#128257
  • Loading branch information
flaub authored and SchmErik committed Jul 29, 2024
1 parent c87955e commit fa14049
Showing 1 changed file with 25 additions and 22 deletions.
47 changes: 25 additions & 22 deletions risc0/circuit/rv32im/src/prove/emu/exec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,10 +378,10 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {
fn ecall_software(&mut self) -> Result<bool> {
tracing::debug!("[{}] ecall_software", self.insn_cycles);
let into_guest_ptr = ByteAddr(self.load_register(REG_A0)?);
if !is_guest_memory(into_guest_ptr.0) && !into_guest_ptr.is_null() {
let into_guest_len = self.load_register(REG_A1)? as usize;
if into_guest_len > 0 && !is_guest_memory(into_guest_ptr.0) {
bail!("{into_guest_ptr:?} is an invalid guest address");
}
let into_guest_len = self.load_register(REG_A1)? as usize;
let name_ptr = self.load_guest_addr_from_register(REG_A2)?;
let syscall_name = self.peek_string(name_ptr)?;
let name_end = name_ptr + syscall_name.len();
Expand Down Expand Up @@ -410,7 +410,7 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {

// The guest uses a null pointer to indicate that a transfer from host
// to guest is not needed.
if !into_guest_ptr.is_null() {
if into_guest_len > 0 && !into_guest_ptr.is_null() {
Self::check_guest_addr(into_guest_ptr + into_guest_len)?;
self.store_region(into_guest_ptr, bytemuck::cast_slice(&syscall.to_guest))?
}
Expand All @@ -431,8 +431,6 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {
tracing::debug!("[{}] ecall_sha", self.insn_cycles);
let state_out_ptr = self.load_guest_addr_from_register(REG_A0)?;
let state_in_ptr = self.load_guest_addr_from_register(REG_A1)?;
let mut block1_ptr = self.load_guest_addr_from_register(REG_A2)?;
let mut block2_ptr = self.load_guest_addr_from_register(REG_A3)?;
let count = self.load_register(REG_A4)?;

let state_in: [u8; DIGEST_BYTES] = self.load_array_from_guest(state_in_ptr)?;
Expand All @@ -441,25 +439,30 @@ impl<'a, 'b, S: Syscall> Executor<'a, 'b, S> {
*word = word.to_be();
}

// tracing::debug!("ecall_sha: start state: {state:08x?}");
let mut block = [0u32; BLOCK_WORDS];
if count > 0 {
let mut block1_ptr = self.load_guest_addr_from_register(REG_A2)?;
let mut block2_ptr = self.load_guest_addr_from_register(REG_A3)?;

for _ in 0..count {
let (digest1, digest2) = block.split_at_mut(DIGEST_WORDS);
for (i, word) in digest1.iter_mut().enumerate() {
*word = self.load_u32_from_guest(block1_ptr + (i * WORD_SIZE))?;
}
for (i, word) in digest2.iter_mut().enumerate() {
*word = self.load_u32_from_guest(block2_ptr + (i * WORD_SIZE))?;
// tracing::debug!("ecall_sha: start state: {state:08x?}");
let mut block = [0u32; BLOCK_WORDS];

for _ in 0..count {
let (digest1, digest2) = block.split_at_mut(DIGEST_WORDS);
for (i, word) in digest1.iter_mut().enumerate() {
*word = self.load_u32_from_guest(block1_ptr + (i * WORD_SIZE))?;
}
for (i, word) in digest2.iter_mut().enumerate() {
*word = self.load_u32_from_guest(block2_ptr + (i * WORD_SIZE))?;
}
// tracing::debug!("Compressing block {block:02x?}");
sha2::compress256(
&mut state,
&[*GenericArray::from_slice(bytemuck::cast_slice(&block))],
);

block1_ptr += BLOCK_BYTES;
block2_ptr += BLOCK_BYTES;
}
// tracing::debug!("Compressing block {block:02x?}");
sha2::compress256(
&mut state,
&[*GenericArray::from_slice(bytemuck::cast_slice(&block))],
);

block1_ptr += BLOCK_BYTES;
block2_ptr += BLOCK_BYTES;
}

// tracing::debug!("ecall_sha: final state: {state:08x?}");
Expand Down

0 comments on commit fa14049

Please sign in to comment.