Technolution / rustig

A tool to detect code paths leading to Rust's panic handler
Apache License 2.0
219 stars 9 forks source link

Feature request: mode to check unsafe code only #24

Open Shnatsel opened 6 years ago

Shnatsel commented 6 years ago

Rustig outputs a lot of places that can panic on real projects. However, in safe code exploiting a panic is not very interesting for an attacker: the best it gets you is denial of service, and there are lots of ways to do that anyway.

However, this is not true for unsafe code. Unsafe Rust needs to uphold certain invariants even in presence of panics, and doing so is far from natural or obvious. There are real vulnerabilities caused by lack of panic safety.

Therefore, it would be nice to have a mode that highlights places that can panic in unsafe code only, to aid in auditing unsafe code.

nbraud commented 6 years ago

@Shnatsel Unfortunately, it's not sufficient to find potential panics in unsafe code, you have to find. within a given module, all potential panics that happen downstream (looking at the CFG) of unsafe code: unsafe code might temporarily violate an invariant, call into safe code, and have the panic happen there before the invariant is established again.

Shnatsel commented 6 years ago

True. And since there is no annotation on when the invariant is established again, automated tools cannot audit just the parts that absolutely require panic safety. Bummer.

nbraud commented 6 years ago

Sorry to rain on your parade :( I would also like a tool that tells me where is the unsafety I need to look at; OTOH, perhaps it would be reasonable to have a mode which reports potential panics only in modules that contain unsafe code?

Shnatsel commented 6 years ago

If a function contains unsafe blocks but is not unsafe to call, the end of the function is where the unsafety is supposed to end. So that's feasible.

If the function is unsafe to call (i.e. it's annotated unsafe fn) then any code using that function should also be checked; but since calling it requires an unsafe block by itself, checking from the start of the unsafe block until the end of the function should cover this case automatically.