immunant / c2rust

Migrate C code to Rust
https://c2rust.com/
Other
3.79k stars 219 forks source link

Support intermediate casts in calls. #1022

Closed aneksteind closed 9 months ago

aneksteind commented 10 months ago

In lighttpd there are intermediate casts where the final cast is an argument to memcpy or memset. Prior to this, only one cast to *libc::c_void was exempted, the final one. Now, all casts are skipped/allowed as long as the final cast serves as input to a function like memcpy or free or realloc. Also, any non-skipped casts into *libc::c_void are now allowed to support cast ancestry that crosses function call boundaries, as the intra-body analysis starting backwards from memset and memcpy does not capture these cases.

The contents of algo_md5.rs match exactly the transpiled output from lighttpd with no alterations made.

spernsteiner commented 10 months ago

any non-skipped casts into *libc::c_void are now allowed to support cast ancestry that crosses function call boundaries

I'm not sure I understand what you mean here. Is this about MD5_Update, where the _input pointer is just passed (through several additional casts) to memcpy? Is the goal to treat MD5_Update(..., input as *const c_void, ...) similar to memcpy(..., input as *const c_void, ...), giving the same special treatment to the input as *const c_void cast?

aneksteind commented 10 months ago

any non-skipped casts into *libc::c_void are now allowed to support cast ancestry that crosses function call boundaries

I'm not sure I understand what you mean here. Is this about MD5_Update, where the _input pointer is just passed (through several additional casts) to memcpy? Is the goal to treat MD5_Update(..., input as *const c_void, ...) similar to memcpy(..., input as *const c_void, ...), giving the same special treatment to the input as *const c_void cast?

@spernsteiner sort of, in particular we exempt the cast in MD5_Update(..., input as *const c_void, ...) because within MD5_Update the casted result is used in memcpy. But to avoid the analysis across boundaries or adding a new pointer permission that gets propagated backwards like free, any casts into a void pointer are now exempted from transmutability checks

spernsteiner commented 10 months ago

I took a look at this, but I'm not sure if this approach of extending CVoidCasts is sufficient to enable the rewrites we want. In particular, I think the proper safe rewrite for this code has MD5_Update taking _input: &[u8] and calling copy_from_slice in place of memcpy. I'll put some more thought into this and try to write something up soon.