facebookexperimental / MIRAI

Rust mid-level IR Abstract Interpreter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Tag analysis fails on container types

hiroki-chen opened this issue · comments

Issue

MIRAI tag analysis would fail unexpectedly when analyzing container types, e.g., Vec, user-defined structs.

Steps to Reproduce

Source code:

#![cfg_attr(mirai, allow(incomplete_features), feature(generic_const_exprs))]

#[macro_use]
extern crate mirai_annotations;

#[cfg(mirai)]
use mirai_annotations::*;

#[cfg(mirai)]
struct SecretTaintKind<const MASK: TagPropagationSet> {}

const MASK: TagPropagationSet = TAG_PROPAGATION_ALL;
#[cfg(mirai)]
type SecretTaint = SecretTaintKind<MASK>;
#[cfg(not(mirai))]
type SecretTaint = (); // Ensures code compiles in non-MIRAI builds

fn foo(v: &Vec<i32>) {
    // This precondition should never be true.
    precondition!(does_not_have_tag!(&v[0], SecretTaint) && has_tag!(&v[0], SecretTaint));
}

fn bar(v: &i32) {
    precondition!(does_not_have_tag!(v, SecretTaint));
}

fn main() {
    let v = vec![1, 2, 3];
    add_tag!(&v, SecretTaint);
    foo(&v);
}

The output is given as follows.

$ cargo mirai
    Checking playground v0.1.0 (/home/kali/playground)
warning: unused `#[macro_use]` import
 --> src/main.rs:3:1
  |
3 | #[macro_use]
  | ^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: `playground` (bin "playground") generated 1 warnings
    Finished dev [unoptimized + debuginfo] target(s) in 0.36s
(base) 

The thing is, MIRAI should give a warning that indicates an unsatisfied precondition but in this case, it failed to do so.

$ cargo mirai
    Checking playground v0.1.0 (/home/test/playground)
warning: unused `#[macro_use]` import
 --> src/main.rs:3:1
  |
3 | #[macro_use]
  | ^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.45s

The above code was tested under the newest version of MIRAI (commit SHA fe1b8989371f16f343191b75555fd5fcf06c733a), but when I tested the some older version of MIRAI (commit SHA f3e8dfc1fc8a86216948fe36d0b6488b16dd5b9a), the report on the unsatisfied precondition would appear.

Besides, #1147 mentions failing tag analysis for type transformation, which, I suspect, may be due to internal bugs related to container types. Moreover, MIRAI will give no warning if given the following code snippet:

fn main() {
    let a = A(1);
    add_tag!(&a, SecretTaint);
    let b = a_to_b(a);
    // verify!(has_tag!(&b, SecretTaint));
    let c = b_to_c(b);
    // verify!(has_tag!(&c, SecretTaint));
}

I.e., if verfiy!s are all removed, then MIRAI will not complain about the unsatisfied precondition for b_to_c, but if verify!(has_tag!(&b, SecretTaint)); is uncommented, then MIRAI would do so.

Hope these bugs can be fixed as soon as possible!

Expected Behavior

MIRAI should complain about the unsatisfied precondition for function call foo.

Actual Results

MIRAI generated no information on unsatisfied preconditions for container types.

Environment

rustc 1.65.0-nightly (d394408fb 2022-08-07)