Last active
March 15, 2018 23:49
-
-
Save astarasikov/93527e6aa4bede41525c86839dcdd253 to your computer and use it in GitHub Desktop.
some macros to taint data with clang static analyzer without modifying and rebuilding llvm source
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#ifndef __CLANG_GHETTO_TAINT__H__ | |
#define __CLANG_GHETTO_TAINT__H__ | |
/****************************************************************************** | |
* Define prototypes for referenced symbols | |
* in case we're in a freestanding environment such as a kernel/bootloader | |
*****************************************************************************/ | |
extern char *getenv(const char *arg); | |
extern int atoi(const char *arg); | |
#define CLANG_TAINT_STRUCT(__expr) do { \ | |
__expr = *(typeof(__expr) *)getenv("foo"); \ | |
} while (0) | |
#define CLANG_TAINT_PTR(__ptr) do { \ | |
__ptr = (typeof(*__ptr) *)getenv("foo"); \ | |
} while (0) | |
#define CLANG_TAINT_AT_PTR(__ptr) do { \ | |
*__ptr = *(typeof(*__ptr) *)getenv("foo"); \ | |
} while (0) | |
#define CLANG_TAINT_INT(__val) do { \ | |
__val = atoi(getenv("yolo1")); \ | |
} while (0) | |
#endif //__CLANG_GHETTO_TAINT__H__ | |
//super ghetto | |
static inline unsigned long copy_from_user(void *to, const void *from, unsigned long n) | |
{ | |
scanf("", to); //works with clang 6.X and up | |
//the advantage over getenv approach is that it works on any pointer expression | |
//and does not need the assignment operator | |
return 0; | |
} | |
int main() { | |
int foo[2]; | |
int bar[3] = {}; | |
int evil_count = 0; | |
struct x { | |
int count; | |
}; | |
struct x str; | |
struct x tmp; | |
struct x *pstr = &tmp; | |
//str = *(struct x*)getenv("foo"); | |
//pstr = (struct x*)getenv("foo"); | |
copy_from_user(&str, 0, 0); | |
copy_from_user(pstr, 0, 0); | |
copy_from_user(&evil_count, 0, 0); | |
memcpy(foo, bar, str.count); | |
memcpy(foo, bar, pstr->count); | |
memcpy(foo, bar, evil_count); | |
/* EXPECT | |
* taint_example.c:43:2: warning: Untrusted data is used to specify the buffer size (CERT/STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator) | |
memcpy(foo, bar, str.count); | |
*/ | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#ifndef __CLANG_GHETTO_TAINT__H__ | |
#define __CLANG_GHETTO_TAINT__H__ | |
/****************************************************************************** | |
* Define prototypes for referenced symbols | |
* in case we're in a freestanding environment such as a kernel/bootloader | |
*****************************************************************************/ | |
extern char *getenv(const char *arg); | |
extern int atoi(const char *arg); | |
#define CLANG_TAINT_STRUCT(__expr) do { \ | |
__expr = *(typeof(__expr) *)getenv("foo"); \ | |
} while (0) | |
#define CLANG_TAINT_PTR(__ptr) do { \ | |
__ptr = (typeof(*__ptr) *)getenv("foo"); \ | |
} while (0) | |
#define CLANG_TAINT_AT_PTR(__ptr) do { \ | |
*__ptr = *(typeof(*__ptr) *)getenv("foo"); \ | |
} while (0) | |
#define CLANG_TAINT_INT(__val) do { \ | |
__val = atoi(getenv("yolo1")); \ | |
} while (0) | |
#endif //__CLANG_GHETTO_TAINT__H__ | |
int main() { | |
int foo[2]; | |
int bar[3] = {}; | |
int evil_count = 0; | |
struct x { | |
int count; | |
}; | |
struct x str; | |
struct x tmp; | |
struct x *pstr = &tmp; | |
CLANG_TAINT_STRUCT(str); | |
CLANG_TAINT_PTR(pstr); | |
CLANG_TAINT_AT_PTR(pstr); | |
CLANG_TAINT_INT(evil_count); | |
//str = *(struct x*)getenv("foo"); | |
//pstr = (struct x*)getenv("foo"); | |
memcpy(foo, bar, str.count); | |
memcpy(foo, bar, pstr->count); | |
memcpy(foo, bar, evil_count); | |
/* EXPECT | |
* taint_example.c:43:2: warning: Untrusted data is used to specify the buffer size (CERT/STR31-C. Guarantee that storage for strings has sufficient space for character data and the null terminator) | |
memcpy(foo, bar, str.count); | |
*/ | |
return 0; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
SCAN_OPTS="\ | |
-enable-checker alpha.core.Conversion \ | |
-enable-checker alpha.core.IdenticalExpr \ | |
-enable-checker alpha.core.PointerArithm \ | |
-enable-checker alpha.core.PointerSub \ | |
-enable-checker alpha.core.SizeofPtr \ | |
-enable-checker alpha.core.TestAfterDivZero \ | |
-enable-checker alpha.security.ArrayBoundV2 \ | |
-enable-checker alpha.security.MallocOverflow \ | |
-enable-checker alpha.security.ReturnPtrRange \ | |
-enable-checker alpha.security.taint.TaintPropagation \ | |
-disable-checker apiModeling.google.GTest \ | |
-disable-checker core.CallAndMessage \ | |
-enable-checker core.DivideZero \ | |
-enable-checker core.DynamicTypePropagation \ | |
-enable-checker core.NonNullParamChecker \ | |
-enable-checker core.NullDereference \ | |
-enable-checker core.StackAddressEscape \ | |
-enable-checker core.UndefinedBinaryOperatorResult \ | |
-enable-checker core.VLASize \ | |
-enable-checker core.builtin.BuiltinFunctions \ | |
-enable-checker core.builtin.NoReturnFunctions \ | |
-enable-checker core.uninitialized.ArraySubscript \ | |
-enable-checker core.uninitialized.Assign \ | |
-enable-checker core.uninitialized.Branch \ | |
-enable-checker core.uninitialized.CapturedBlockVariable \ | |
-enable-checker core.uninitialized.UndefReturn \ | |
-disable-checker cplusplus.NewDelete \ | |
-disable-checker cplusplus.NewDeleteLeaks \ | |
-disable-checker cplusplus.SelfAssignment \ | |
-disable-checker deadcode.DeadStores \ | |
-enable-checker nullability.NullPassedToNonnull \ | |
-enable-checker nullability.NullReturnedFromNonnull \ | |
-enable-checker nullability.NullableDereferenced \ | |
-enable-checker nullability.NullablePassedToNonnull \ | |
-enable-checker nullability.NullableReturnedFromNonnull \ | |
-disable-checker osx.API \ | |
-disable-checker osx.NumberObjectConversion \ | |
-disable-checker osx.ObjCProperty \ | |
-disable-checker osx.SecKeychainAPI \ | |
-disable-checker osx.cocoa.AtSync \ | |
-disable-checker osx.cocoa.ClassRelease \ | |
-disable-checker osx.cocoa.Dealloc \ | |
-disable-checker osx.cocoa.IncompatibleMethodTypes \ | |
-disable-checker osx.cocoa.Loops \ | |
-disable-checker osx.cocoa.MissingSuperCall \ | |
-disable-checker osx.cocoa.NSAutoreleasePool \ | |
-disable-checker osx.cocoa.NSError \ | |
-disable-checker osx.cocoa.NilArg \ | |
-disable-checker osx.cocoa.NonNilReturnValue \ | |
-disable-checker osx.cocoa.ObjCGenerics \ | |
-disable-checker osx.cocoa.RetainCount \ | |
-disable-checker osx.cocoa.SelfInit \ | |
-disable-checker osx.cocoa.SuperDealloc \ | |
-disable-checker osx.cocoa.UnusedIvars \ | |
-disable-checker osx.cocoa.VariadicMethodTypes \ | |
-disable-checker osx.coreFoundation.CFError \ | |
-disable-checker osx.coreFoundation.CFNumber \ | |
-disable-checker osx.coreFoundation.CFRetainRelease \ | |
-disable-checker osx.coreFoundation.containers.OutOfBounds \ | |
-disable-checker osx.coreFoundation.containers.PointerSizedValues \ | |
-enable-checker security.insecureAPI.UncheckedReturn \ | |
-disable-checker security.insecureAPI.getpw \ | |
-disable-checker security.insecureAPI.gets \ | |
-disable-checker security.insecureAPI.mkstemp \ | |
-disable-checker security.insecureAPI.mktemp \ | |
-disable-checker security.insecureAPI.rand \ | |
-enable-checker security.insecureAPI.strcpy \ | |
-disable-checker security.insecureAPI.vfork \ | |
-enable-checker unix.API \ | |
-enable-checker unix.Malloc \ | |
-enable-checker unix.MallocSizeof \ | |
-enable-checker unix.MismatchedDeallocator \ | |
-enable-checker unix.StdCLibraryFunctions \ | |
-enable-checker unix.Vfork \ | |
-enable-checker unix.cstring.BadSizeArg \ | |
-enable-checker unix.cstring.NullArg \ | |
" | |
DEBUG_OPTS="\ | |
-enable-checker debug.AnalysisOrder \ | |
-enable-checker debug.DumpCalls \ | |
-enable-checker debug.DumpCFG \ | |
-enable-checker debug.DumpCallGraph \ | |
-enable-checker debug.TaintTest \ | |
" | |
export PATH=/Users/alexander/Documents/workspace/builds/llvm/build/bin/:$PATH | |
#scan-build ${SCAN_OPTS} -k clang -c taint_example.c | |
scan-build ${SCAN_OPTS} -k clang -c taint_cfu.c |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
SCAN_OPTS="\ | |
-analyze-headers \ | |
-maxloop 20 \ | |
-enable-checker alpha.core.Conversion \ | |
-enable-checker alpha.core.IdenticalExpr \ | |
-enable-checker alpha.core.PointerArithm \ | |
-enable-checker alpha.core.PointerSub \ | |
-enable-checker alpha.core.SizeofPtr \ | |
-enable-checker alpha.core.TestAfterDivZero \ | |
-enable-checker alpha.security.ArrayBoundV2 \ | |
-enable-checker alpha.security.MallocOverflow \ | |
-enable-checker alpha.security.ReturnPtrRange \ | |
-enable-checker alpha.security.taint.TaintPropagation \ | |
-disable-checker apiModeling.google.GTest \ | |
-disable-checker core.CallAndMessage \ | |
-enable-checker core.DivideZero \ | |
-enable-checker core.DynamicTypePropagation \ | |
-enable-checker core.NonNullParamChecker \ | |
-enable-checker core.NullDereference \ | |
-enable-checker core.StackAddressEscape \ | |
-enable-checker core.UndefinedBinaryOperatorResult \ | |
-enable-checker core.VLASize \ | |
-enable-checker core.builtin.BuiltinFunctions \ | |
-enable-checker core.builtin.NoReturnFunctions \ | |
-enable-checker core.uninitialized.ArraySubscript \ | |
-enable-checker core.uninitialized.Assign \ | |
-enable-checker core.uninitialized.Branch \ | |
-enable-checker core.uninitialized.CapturedBlockVariable \ | |
-enable-checker core.uninitialized.UndefReturn \ | |
-disable-checker cplusplus.NewDelete \ | |
-disable-checker cplusplus.NewDeleteLeaks \ | |
-disable-checker cplusplus.SelfAssignment \ | |
-disable-checker deadcode.DeadStores \ | |
-enable-checker nullability.NullPassedToNonnull \ | |
-enable-checker nullability.NullReturnedFromNonnull \ | |
-enable-checker nullability.NullableDereferenced \ | |
-enable-checker nullability.NullablePassedToNonnull \ | |
-enable-checker nullability.NullableReturnedFromNonnull \ | |
-disable-checker osx.API \ | |
-disable-checker osx.NumberObjectConversion \ | |
-disable-checker osx.ObjCProperty \ | |
-disable-checker osx.SecKeychainAPI \ | |
-disable-checker osx.cocoa.AtSync \ | |
-disable-checker osx.cocoa.ClassRelease \ | |
-disable-checker osx.cocoa.Dealloc \ | |
-disable-checker osx.cocoa.IncompatibleMethodTypes \ | |
-disable-checker osx.cocoa.Loops \ | |
-disable-checker osx.cocoa.MissingSuperCall \ | |
-disable-checker osx.cocoa.NSAutoreleasePool \ | |
-disable-checker osx.cocoa.NSError \ | |
-disable-checker osx.cocoa.NilArg \ | |
-disable-checker osx.cocoa.NonNilReturnValue \ | |
-disable-checker osx.cocoa.ObjCGenerics \ | |
-disable-checker osx.cocoa.RetainCount \ | |
-disable-checker osx.cocoa.SelfInit \ | |
-disable-checker osx.cocoa.SuperDealloc \ | |
-disable-checker osx.cocoa.UnusedIvars \ | |
-disable-checker osx.cocoa.VariadicMethodTypes \ | |
-disable-checker osx.coreFoundation.CFError \ | |
-disable-checker osx.coreFoundation.CFNumber \ | |
-disable-checker osx.coreFoundation.CFRetainRelease \ | |
-disable-checker osx.coreFoundation.containers.OutOfBounds \ | |
-disable-checker osx.coreFoundation.containers.PointerSizedValues \ | |
-enable-checker security.insecureAPI.UncheckedReturn \ | |
-disable-checker security.insecureAPI.getpw \ | |
-disable-checker security.insecureAPI.gets \ | |
-disable-checker security.insecureAPI.mkstemp \ | |
-disable-checker security.insecureAPI.mktemp \ | |
-disable-checker security.insecureAPI.rand \ | |
-enable-checker security.insecureAPI.strcpy \ | |
-disable-checker security.insecureAPI.vfork \ | |
-enable-checker unix.API \ | |
-enable-checker unix.Malloc \ | |
-enable-checker unix.MallocSizeof \ | |
-enable-checker unix.MismatchedDeallocator \ | |
-enable-checker unix.StdCLibraryFunctions \ | |
-enable-checker unix.Vfork \ | |
-enable-checker unix.cstring.BadSizeArg \ | |
-enable-checker unix.cstring.NullArg \ | |
" | |
DEBUG_OPTS="\ | |
-enable-checker debug.AnalysisOrder \ | |
-enable-checker debug.DumpCalls \ | |
-enable-checker debug.DumpCFG \ | |
-enable-checker debug.DumpCallGraph \ | |
-enable-checker debug.TaintTest \ | |
" | |
export SUBARCH=arm64 | |
export ARCH=arm64 | |
export SDIRS="\ | |
drivers/ | |
" | |
export PATH=/Users/alexander/Documents/workspace/builds/llvm/build/bin/:$PATH | |
find ${SDIRS} -name '*.o' -delete | |
scan-build ${SCAN_OPTS} -k --use-cc /Users/alexander/Documents/workspace/bin/toolchains/aarch64-linux-android-4.9-master/bin/aarch64-linux-android-gcc --analyzer-target aarch64--linux make -j8 -k ${SDIRS} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also consider https://github.com/vlad902/kernel-intoverflow-taint-checker