Audit trail & MIR


#1

I was discussing the possibility of tracking audit trails using an attribute, as outlined here, with a friend earlier today. Our conversation centered around what it means for code to be auditable, and I raised my concern that an attribute is the wrong place to track audit trail, because the trail needs to be invalidated if the audited block changes.

After pondering for some time, he mused that it’s ok for the inspected code to change, so long as the emitted code doesn’t change. (This line of reasoning isn’t entirely accurate, but it’s close enough for the time being.) This led me to wonder whether, conceptually, it would be feasible to export the MIR for the audited block, and if so, in broad strokes, how might that be done?

The idea-at-large is to track audit trail largely in source control (say, as git notes). An auditing tool could scan for #[safe] blocks, generate their MIR, and attach it in the note as audit data. If the audited code is changed, the tool would generate new MIR and compare it to the stored MIR. If the MIR changed, it would flag the block to be re-audited.

Now that I’ve written it out, the idea seems ludicrous, but I don’t know enough about Rust to truly discount it. Could someone point out where I might start learning about it?


#2

I’m not sure this is even possible in principle just because functions can be inlined. Since inlining can happen in LLVM and in MIR (and I think const eval?), I’m not sure that a “inline nothing so I can audit stuff” mode is even possible to implement in practice. I think monomorphization happens strictly post-MIR today so we can ignore that… though I really don’t know any of this for sure, actual compiler people would have to confirm.

More fundamentally, it’s not obvious to me that “emits the same MIR” gives us any strong safety guarantees that would matter for auditing purposes. I wouldn’t be surprised if there are examples of unsafe code that triggers undefined behavior but happens to “work”, and emits exactly the same MIR as some other perfectly valid block of code.

Wouldn’t a hash or signature of the actual source code be more straightforward than a dump of the MIR, and just as useful for auditing? (I’m trying to ignore the question of whether any variation of this is useful for auditing at all, since it’s not really your question, and I personally have no idea either way)


#3

I agree, the MIR comparison can’t work at all for unsafe code because undefined behavior is possible (especially in FFI). The audit tools would always signal unsafe blocks for audit. I assume, however, that the safe attribute has a wider applicability than unsafe blocks. That is, that MIR comparisons could be useful for not-unsafe code, where UB doesn’t exist.

I imagine I’d use a hash or signature to identify whether the code changed. The MIR comparison, assuming it’s even possible, would be applied after change detection to determine whether the change materially affected the compiled code. (I’d use it to cull false positives.)

I called it ludicrous for a reason. :wink: