[cfe-dev] Clang GenericTaintChecker limitations

Artem Dergachev via cfe-dev cfe-dev at lists.llvm.org
Fri Aug 19 03:59:59 PDT 2016

Hmm, that's because your globals are invalidated on every conservatively 
evaluated call, including taint_add(). You might need to evalCall 
taint_add(). To emulate how it would work, you can replace the 
taint_add() prototype with:

   void taint_add(item **it) {}

(empty body, but post-call still happens, so GenericTaint still operates 


Now, once we do that, we run into a real bug: on my system i'm seeing 
some library functions invalidate globals, such as memcpy(), which is 
actually __builtin___memcpy_chk().

Naturally, a conservatively evaluated function may touch any global, so 
it's normal to invalidate globals.

However, a system library function shouldn't be touching user's globals, 
and so user's globals are not invalidated upon conservatively evaluating 
functions that have their prototypes coming from system headers.

Unfortunately, some of the builtins, such as __builtin___memcpy_chk(), 
are not coming from the system headers! And this exceptional case seems 
to be forgotten in the analyzer. I've attached a quick proof-of-concept 
patch, and i'm planning to fix this properly soon.


With these two changes, taint works for me. But any conservative 
non-system-header call would break it again, and there's not much we can do.

On 8/18/16 5:05 PM, Divya Muthukumaran wrote:
> Hi Artem,
> Thanks for sending that -- I commented out those lines in the source 
> and recompiled and the taint propagates correctly for the example I 
> sent you.
> But then I changed the code slightly, so that instead of storing the 
> items in a list, I store them in an array. New items are added to an 
> offset of the
> array address (i.e., array[OFFSET] = new_item). Now the taint doesn't 
> propagate at all. Is there something about array modelling that is 
> different?
> I have attached my revised test case with this email. Note that if I 
> replace A1 with A2 and B1 with B2 or hard code the offset into the array
> the taint propagates correctly.
> Thanks,
> Divya

-------------- next part --------------
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
index 89610ef..685abc0 100644
--- a/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
+++ b/include/clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h
@@ -237,6 +237,10 @@ public:
     if (!D)
       return false;
+    if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
+      if (StringRef(FD->getNameAsString()).startswith("__builtin"))
+        return true;
     SourceLocation Loc = D->getLocation();
     if (Loc.isValid()) {
       const SourceManager &SM =

More information about the cfe-dev mailing list