-
Notifications
You must be signed in to change notification settings - Fork 64
Open
Description
Entering a function causes the field-level precision to be lost if the child function does not access the fields. The following example illustrates this
fn id_fun<T, G>(obj: (T, G)) -> (T, G) {
obj
}
fn no_overtaint_over_fn_call() {
let p = input();
let q = input();
let t = id_fun((p, q));
read(t.0);
read2(t.1);
}
// external functions
fn input() -> usize;
fn read<T>(recv1: T);
fn read2<T>(recv2: T);The PDG shows paths p -> recv2 and q -> recv1, which are caused because obj is tracked as a single object. E.g. there are edges p -> obj and q -> obj as well as obj -> revc1 and obj -> recv2.
That is to say the PDG for id_fun does not track obj.0 and obj.1 as separate nodes and as a result the caller loses that precision also.
The same effect can be observed for nested functions, e.g.
fn main() {
let p = input();
let q = input();
forwarder((p, q));
}
fn forwarder(t: (usize, usize)) {
acceptor(t)
}
fn acceptor(b: (usize, usize)) {
read(b.0);
read2(b.1);
}Here we observe p -> t and q -> t as well as t -> b.0 and t -> b.1. What we would expect is p -> t.0 -> b.0 and q -> t.1 -> b.1.
Metadata
Metadata
Assignees
Labels
No labels