 
 
 
 
 
 
   
As described in Section 2.3, we use a conservative rule for pointer subtyping. This rule can lead to non-intuitive reverse taint flow, which often causes false positives. For example, consider the following code:
  f(const char *x);
  char *unclean, *clean;
  unclean = getenv("PATH");
  f(unclean);
  f(clean); /* 'clean' gets tainted */
Here the getenv() function call imposes the condition
 .
The first call to f adds the constraint
.
The first call to f adds the constraint
 .
The second function call generates the constraint
.
The second function call generates the constraint
 ,
thereby marking *clean as tainted,
which is counter-intuitive.
,
thereby marking *clean as tainted,
which is counter-intuitive.
Observe, however, that f's argument x is of type const char *, so f can not make *x tainted if it is not tainted in the first place. Consequently, we modify the constraints in Section 2 as follows: For an assignment
const char *s; char *t; ... s = t;we add the constraints
 and
 and 
 , if *s has a const qualifier.
This is to be compared with the constraint
, if *s has a const qualifier.
This is to be compared with the constraint 
 which we would otherwise have imposed.
In this way we can use ``deep subtyping'' to improve precision
for formal parameters marked const.
 which we would otherwise have imposed.
In this way we can use ``deep subtyping'' to improve precision
for formal parameters marked const.
This extra precision, which helps avoid many false positives (especially in library functions), is the main reason we work in a subtyping system. Note that we rely on the C compiler to warn the programmer about any casts which discard the const qualifier, i.e., we assume that a variable that is const is never cast to anything that is not const.
 
 
 
 
