analyze: "known permissions changed" on lighttpd libc calls
-
known permissions changed for DefId(0:39 ~ lighttpd_rust_amalgamated[c1eb]::{extern#0}::getenv): LFnSig { inputs: [g1868#*const i8[NONE#i8[]]], output: g1869#*mut i8[NONE#i8[]] } known permissions changed for PointerId g1869: READ | OFFSET_ADD -> READ | OFFSET_ADD | OFFSET_SUBfn getenv( s: *const c_char: [READ | OFFSET_ADD | NON_NULL], // Not `WRITE` even though it's `*mut` since future calls may overwrite the returned memory, // as it may be statically allocated and reused. It is not meant to be modified. ) -> *mut c_char: [READ | OFFSET_ADD];I think the return type here just needs
OFFSET_SUBadded. -
known permissions changed for DefId(0:28 ~ lighttpd_rust_amalgamated[c1eb]::{extern#0}::strtoll): LFnSig { inputs: [g1860#*const i8[NONE#i8[]], g1861#*mut *mut i8[g1862#*mut i8[NONE#i8[]]], NONE#i32[]], output: NONE#i64[] } known permissions changed for PointerId g1862: WRITE | OFFSET_ADD -> READ | WRITE | OFFSET_ADD | OFFSET_SUBfn strtoll( s: *const c_char: [READ | OFFSET_ADD | NON_NULL], endp: *mut *mut c_char: [WRITE, WRITE | OFFSET_ADD], base: c_int, ) -> c_longlong;The permission on
*endp(the inner*mut char) has gainedREADandOFFSET_SUB. This is a bit tricky because our handling of pointer-to-pointer means the inner pointer's permissions in the signature must be equal to the permissions of the pointer passed in at the call site (whereas for outermost pointers, we only require a subset/superset). This means it may gain extra permissions based on what happens to the argument both before and after the call. We may need a special case in the final "known permissions changed" check so we can be more specific about what exactly is required/guaranteed here.
We may discover more cases like this as we expand the analysis to handle more of lighttpd.