sampsyo / quala

custom type systems for Clang
MIT License
96 stars 7 forks source link

Set annotation for elements in c `struct`. #12

Open EmmetZC opened 7 years ago

EmmetZC commented 7 years ago

Hi, me again. The tainting for struct types is not working as I expected. I don't know if there's any misunderstanding here. Check the code below:

typedef struct {
  int x;
  int y;
} Point;

void main(){
  TAINED Point *tp = malloc(sizeof(Point));
  Point a = *tp; // (1)
  int x = tp->x; // (2)
}

For my idea, both assignments (1) and (2) are illegal and cause an error assigning a tainted value to a normal variable, while in fact, only (1) causes an error and (2) is fine, because quala doesn't treat tp->x as a tainted value.

From this test above, I may infer that quala thinks the elements in a tainted struct are not tainted. Is this how you think the tainting should be like, or, maybe you have implemented it in a wrong way?

sampsyo commented 7 years ago

Hi again!

You're right; that's exactly how the checker works. I agree that it's probably not a great implementation of taint tracking—it would probably be a good idea to add a new rule that taints the fields of tainted structs. But just to be clear, that's a design decision: you could also decide that the tainting of struct values is distinct from the tainting of individual fields. We just haven't implemented the more sophisticated strategy yet.

EmmetZC commented 7 years ago

Hi, many thanks for your response. I override the method VisitMemberExpr () in TaintTracking.cpp and now it gives an error for line (2) above, just as I expected. But now I get a further question with the LLVM IR instructions generated. Check code below:

typedef struct {
  int x;
  int y;
} Point;

void main(){
  TAINTED Point *tp = malloc(sizeof(Point));
  TAINTED int *x = malloc(sizeof(int));
  tp->x = 10;
  *x = 6;
}

The generated LLVM IR is:

; Function Attrs: nounwind
define void @main() #0 {
entry:
  ...
  %x2 = getelementptr inbounds %struct.Point, %struct.Point* %2, i32 0, i32 0
  store i32 10, i32* %x2, align 4 // (a)stores 10 to p->x
  %3 = load i32*, i32** %x, align 4
  store i32 6, i32* %3, align 4, !tyann !1 // (b)stores 6 to *x
  ret void
}

Check out IR(a) and IR(b) generated. (b) is easy to understand since we set x to be TAINTED int * type, thus the store instruction has a metadata "!tyann !1". What is curious is that instruction(a) has no such metadata. I mean, I've call AddAnnotation for the MemberExpr object in function VisitMemberExpr, why does the store instruction still have no annotation metadata?

Could you please tell me how I can make the store instruction of p->x annotated, just like the store instruction of *x, please?

Many thanks for your time.

sampsyo commented 7 years ago

Aha; tricky! I don't have any immediate advice for you (this would take me a little too much time to sort out on my end). But I think that you might need to hack the codegen layer in clang-quala to make this work—I don't currently see a way around that.

EmmetZC commented 7 years ago

Alright, I see. Thanks a lot.