Skip to content

Instantly share code, notes, and snippets.

@astarasikov
Last active March 15, 2018 23:49
Show Gist options
  • Save astarasikov/93527e6aa4bede41525c86839dcdd253 to your computer and use it in GitHub Desktop.
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
#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;
}
#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;
}
#!/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
#!/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}
@astarasikov
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment