849 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			849 lines
		
	
	
		
			23 KiB
		
	
	
	
		
			HTML
		
	
	
	
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
 | |
|           "http://www.w3.org/TR/html4/strict.dtd">
 | |
| <html>
 | |
| <head>
 | |
|   <title>Alpha Checks</title>
 | |
|   <link type="text/css" rel="stylesheet" href="menu.css">
 | |
|   <link type="text/css" rel="stylesheet" href="content.css">
 | |
|   <script type="text/javascript" src="scripts/menu.js"></script>
 | |
|   <script type="text/javascript" src="scripts/expandcollapse.js"></script>
 | |
|   <style type="text/css">
 | |
|   tr:first-child { width:20%; }
 | |
|   </style>
 | |
| </head>
 | |
| <body onload="initExpandCollapse()">
 | |
| 
 | |
| <div id="page">
 | |
| <!--#include virtual="menu.html.incl"-->
 | |
| 
 | |
| <div id="content">
 | |
| <h1>Alpha Checkers</h1>
 | |
| Experimental checkers in addition to the <a href = "available_checks.html">
 | |
| Default Checkers</a>. These are checkers with known issues or limitations that
 | |
| keep them from being on by default. They are likely to have false positives.
 | |
| Bug reports are welcome but will likely not be investigated for some time.
 | |
| Patches welcome!
 | |
| <ul>
 | |
| <li><a href="#core_alpha_checkers">Core Alpha Checkers</a></li>
 | |
| <li><a href="#cplusplus_alpha_checkers">C++ Alpha Checkers</a></li>
 | |
| <li><a href="#deadcode_alpha_checkers">Dead Code Alpha Checkers</a></li>
 | |
| <li><a href="#osx_alpha_checkers">OS X Alpha Checkers</a></li>
 | |
| <li><a href="#security_alpha_checkers">Security Alpha Checkers</a></li>
 | |
| <li><a href="#unix_alpha_checkers">Unix Alpha Checkers</a></li>
 | |
| </ul>
 | |
| 
 | |
| <!------------------------------ core alpha ----------------------------------->
 | |
| <h3 id="core_alpha_checkers">Core Alpha Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.BoolAssignment</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warn about assigning non-{0,1} values to boolean variables.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   BOOL b = -1; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.CastSize</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check when casting a malloc'ed type T, whether the size is a multiple of the 
 | |
| size of T (Works only with <span class="name">unix.Malloc</span>
 | |
| or <span class="name">alpha.unix.MallocWithAnnotations</span> 
 | |
| checks enabled).</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *x = (int *)malloc(11); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.CastToStruct</span><span class="lang">
 | |
| (C, C++)</span><div class="descr">
 | |
| Check for cast from non-struct pointer to struct pointer.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| struct s {};
 | |
| 
 | |
| void test(int *p) {
 | |
|   struct s *ps = (struct s *) p; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // C++
 | |
| class c {};
 | |
| 
 | |
| void test(int *p) {
 | |
|   c *pc = (c *) p; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.FixedAddr</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for assignment of a fixed address to a pointer.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p;
 | |
|   p = (int *) 0x10000; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.IdenticalExpr</span><span class="lang">
 | |
| (C, C++)</span><div class="descr">
 | |
| Warn about suspicious uses of identical expressions.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| void test() {
 | |
|   int a = 5;
 | |
|   int b = a | 4 | a; // warn: identical expr on both sides
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // C++
 | |
| bool f(void);
 | |
| 
 | |
| void test(bool b) {
 | |
|   int i = 10;
 | |
|   if (f()) { // warn: true and false branches are identical
 | |
|     do {
 | |
|       i--;
 | |
|     } while (f());
 | |
|   } else {
 | |
|     do {
 | |
|       i--;
 | |
|     } while (f());
 | |
|   }
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.PointerArithm</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for pointer arithmetic on locations other than array 
 | |
| elements.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x;
 | |
|   int *p;
 | |
|   p = &x + 1; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.PointerSub</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for pointer subtractions on two pointers pointing to different memory 
 | |
| chunks.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int x, y;
 | |
|   int d = &y - &x; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.core.SizeofPtr</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn about unintended use of <code>sizeof()</code> on pointer 
 | |
| expressions.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| struct s {};
 | |
| 
 | |
| int test(struct s *p) {
 | |
|   return sizeof(p); 
 | |
|     // warn: sizeof(ptr) can produce an unexpected result
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!--------------------------- cplusplus alpha --------------------------------->
 | |
| <h3 id="cplusplus_alpha_checkers">C++ Alpha Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.cplusplus.NewDeleteLeaks</span><span class="lang">
 | |
| (C++)</span><div class="descr">
 | |
| Check for memory leaks. Traces memory managed by <code>new</code>/<code>
 | |
| delete</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int *p = new int;
 | |
| } // warn
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.cplusplus.VirtualCall</span><span class="lang">
 | |
| (C++)</span><div class="descr">
 | |
| Check virtual member function calls during construction or 
 | |
| destruction.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| class A {
 | |
| public:
 | |
|   A() { 
 | |
|     f(); // warn
 | |
|   }
 | |
|   virtual void f();
 | |
| };
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| class A {
 | |
| public:
 | |
|   ~A() {
 | |
|     this->f(); // warn
 | |
|   }
 | |
|   virtual void f();
 | |
| };
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!--------------------------- dead code alpha --------------------------------->
 | |
| <h3 id="deadcode_alpha_checkers">Dead Code Alpha Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.deadcode.UnreachableCode</span><span class="lang">
 | |
| (C, C++, ObjC)</span><div class="descr">
 | |
| Check unreachable code.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| // C
 | |
| int test() {
 | |
|   int x = 1;
 | |
|   while(x);
 | |
|   return x; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // C++
 | |
| void test() {
 | |
|   int a = 2;
 | |
| 
 | |
|   while (a > 1)
 | |
|     a--;
 | |
| 
 | |
|   if (a > 1)
 | |
|     a++; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // Objective-C
 | |
| void test(id x) {
 | |
|   return;
 | |
|   [x retain]; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| </tbody></table>
 | |
| 
 | |
| <!---------------------------- OS X alpha -------------------------------------->
 | |
| <h3 id="osx_alpha_checkers">OS X Alpha Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.osx.cocoa.Dealloc</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Warn about Objective-C classes that lack a correct implementation 
 | |
| of <code>-dealloc</code>.
 | |
| </div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {
 | |
|   id _myproperty;  
 | |
| }
 | |
| @end
 | |
| 
 | |
| @implementation MyObject // warn: lacks 'dealloc'
 | |
| @end
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {}
 | |
| @property(assign) id myproperty;
 | |
| @end
 | |
| 
 | |
| @implementation MyObject // warn: does not send 'dealloc' to super
 | |
| - (void)dealloc {
 | |
|   self.myproperty = 0;
 | |
| }
 | |
| @end
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {
 | |
|   id _myproperty;
 | |
| }
 | |
| @property(retain) id myproperty;
 | |
| @end
 | |
| 
 | |
| @implementation MyObject
 | |
| @synthesize myproperty = _myproperty;
 | |
|   // warn: var was retained but wasn't released
 | |
| - (void)dealloc {
 | |
|   [super dealloc];
 | |
| }
 | |
| @end
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| @interface MyObject : NSObject {
 | |
|   id _myproperty;
 | |
| }
 | |
| @property(assign) id myproperty;
 | |
| @end
 | |
| 
 | |
| @implementation MyObject
 | |
| @synthesize myproperty = _myproperty;
 | |
|   // warn: var wasn't retained but was released
 | |
| - (void)dealloc {
 | |
|   [_myproperty release];
 | |
|   [super dealloc];
 | |
| }
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check that Objective C properties follow the following rule: the property 
 | |
| should be set with the setter, not though a direct assignment.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyClass : NSObject {}
 | |
| @property (readonly) id A;
 | |
| - (void) foo;
 | |
| @end
 | |
| 
 | |
| @implementation MyClass
 | |
| - (void) foo {
 | |
|   _A = 0; // warn
 | |
| }
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.osx.cocoa.DirectIvarAssignmentForAnnotatedFunctions</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check for direct assignments to instance variables in the methods annotated 
 | |
| with <code>objc_no_direct_instance_variable_assignment</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @interface MyClass : NSObject {}
 | |
| @property (readonly) id A;
 | |
| - (void) fAnnotated __attribute__((
 | |
|     annotate("objc_no_direct_instance_variable_assignment")));
 | |
| - (void) fNotAnnotated;
 | |
| @end
 | |
| 
 | |
| @implementation MyClass
 | |
| - (void) fAnnotated {
 | |
|   _A = 0; // warn
 | |
| }
 | |
| - (void) fNotAnnotated {
 | |
|   _A = 0; // no warn
 | |
| }
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.osx.cocoa.InstanceVariableInvalidation</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check that the invalidatable instance variables are invalidated in the methods
 | |
| annotated with <code>objc_instance_variable_invalidator</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @protocol Invalidation <NSObject>
 | |
| - (void) invalidate 
 | |
|   __attribute__((annotate("objc_instance_variable_invalidator")));
 | |
| @end 
 | |
| 
 | |
| @interface InvalidationImpObj : NSObject <Invalidation>
 | |
| @end
 | |
| 
 | |
| @interface SubclassInvalidationImpObj : InvalidationImpObj {
 | |
|   InvalidationImpObj *var;
 | |
| }
 | |
| - (void)invalidate;
 | |
| @end
 | |
| 
 | |
| @implementation SubclassInvalidationImpObj
 | |
| - (void) invalidate {}
 | |
| @end
 | |
| // warn: var needs to be invalidated or set to nil
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.osx.cocoa.MissingInvalidationMethod</span><span class="lang">
 | |
| (ObjC)</span><div class="descr">
 | |
| Check that the invalidation methods are present in classes that contain 
 | |
| invalidatable instance variables.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| @protocol Invalidation <NSObject>
 | |
| - (void)invalidate 
 | |
|   __attribute__((annotate("objc_instance_variable_invalidator")));
 | |
| @end
 | |
| 
 | |
| @interface NeedInvalidation : NSObject <Invalidation>
 | |
| @end
 | |
| 
 | |
| @interface MissingInvalidationMethodDecl : NSObject {
 | |
|   NeedInvalidation *Var; // warn
 | |
| }
 | |
| @end
 | |
| 
 | |
| @implementation MissingInvalidationMethodDecl
 | |
| @end
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!------------------------- security alpha ------------------------------------>
 | |
| <h3 id="security_alpha_checkers">Security Alpha Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.security.ArrayBound</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn about buffer overflows (older checker).</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char *s = "";
 | |
|   char c = s[1]; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| struct seven_words {
 | |
|   int c[7];
 | |
| };
 | |
| 
 | |
| void test() {
 | |
|   struct seven_words a, *p;
 | |
|   p = &a;
 | |
|   p[0] = a;
 | |
|   p[1] = a;
 | |
|   p[2] = a; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // note: requires unix.Malloc or 
 | |
| // alpha.unix.MallocWithAnnotations checks enabled.
 | |
| void test() {
 | |
|   int *p = malloc(12);
 | |
|   p[3] = 4; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char a[2];
 | |
|   int *b = (int*)a;
 | |
|   b[1] = 3; // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.security.ArrayBoundV2</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Warn about buffer overflows (newer checker).</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char *s = "";
 | |
|   char c = s[1]; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int buf[100];
 | |
|   int *p = buf;
 | |
|   p = p + 99;
 | |
|   p[1] = 1; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // note: compiler has internal check for this.
 | |
| // Use -Wno-array-bounds to suppress compiler warning.
 | |
| void test() {
 | |
|   int buf[100][100];
 | |
|   buf[0][-1] = 1; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // note: requires alpha.security.taint check turned on.
 | |
| void test() {
 | |
|   char s[] = "abc";
 | |
|   int x = getchar();
 | |
|   char c = s[x]; // warn: index is tainted
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.security.MallocOverflow</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for overflows in the arguments to <code>malloc()</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test(int n) {
 | |
|   void *p = malloc(n * sizeof(int)); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.security.ReturnPtrRange</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for an out-of-bound pointer being returned to callers.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| static int A[10];
 | |
| 
 | |
| int *test() {
 | |
|   int *p = A + 10;
 | |
|   return p; // warn
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| int test(void) {
 | |
|   int x;
 | |
|   return x; // warn: undefined or garbage returned
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.security.taint.TaintPropagation</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Generate taint information used by other checkers.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   char x = getchar(); // 'x' marked as tainted
 | |
|   system(&x); // warn: untrusted data is passed to a system call
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| // note: compiler internally checks if the second param to
 | |
| // sprintf is a string literal or not. 
 | |
| // Use -Wno-format-security to suppress compiler warning.
 | |
| void test() {
 | |
|   char s[10], buf[10];
 | |
|   fscanf(stdin, "%s", s); // 's' marked as tainted
 | |
| 
 | |
|   sprintf(buf, s); // warn: untrusted data as a format string
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   size_t ts;
 | |
|   scanf("%zd", &ts); // 'ts' marked as tainted
 | |
|   int *p = (int *)malloc(ts * sizeof(int)); 
 | |
|     // warn: untrusted data as bufer size
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| <!--------------------------- unix alpha -------------------------------------->
 | |
| <h3 id="unix_alpha_checkers">Unix Alpha Checkers</h3>
 | |
| <table class="checkers">
 | |
| <colgroup><col class="namedescr"><col class="example"></colgroup>
 | |
| <thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
 | |
| 
 | |
| <tbody>
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.Chroot</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check improper use of <code>chroot</code>.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void f();
 | |
| 
 | |
| void test() {
 | |
|   chroot("/usr/local");
 | |
|   f(); // warn: no call of chdir("/") immediately after chroot
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.MallocWithAnnotations</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for memory leaks, double free, and use-after-free problems. Assumes that
 | |
| all user-defined functions which might free a pointer are
 | |
| annotated.</div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
 | |
| 
 | |
| void test() {
 | |
|   int *p = my_malloc(1);
 | |
| } // warn: potential leak
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
 | |
| void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 | |
| 
 | |
| void test() {
 | |
|   int *p = my_malloc(1);
 | |
|   my_free(p);
 | |
|   my_free(p); // warn: attempt to free released
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
 | |
| void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
 | |
| 
 | |
| void test() {
 | |
|   int *p = my_malloc(1);
 | |
|   my_hold(p);
 | |
|   free(p); // warn: attempt to free non-owned memory
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void __attribute((ownership_takes(malloc, 1))) my_free(void *);
 | |
| 
 | |
| void test() {
 | |
|   int *p = malloc(1);
 | |
|   my_free(p);
 | |
|   *p = 1; // warn: use after free
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.PthreadLock</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Simple lock -> unlock checker; applies to:<div class=functions>
 | |
| pthread_mutex_lock<br>
 | |
| pthread_rwlock_rdlock<br>
 | |
| pthread_rwlock_wrlock<br>
 | |
| lck_mtx_lock<br>
 | |
| lck_rw_lock_exclusive<br>
 | |
| lck_rw_lock_shared<br>
 | |
| pthread_mutex_trylock<br>
 | |
| pthread_rwlock_tryrdlock<br>
 | |
| pthread_rwlock_tryrwlock<br>
 | |
| lck_mtx_try_lock<br>
 | |
| lck_rw_try_lock_exclusive<br>
 | |
| lck_rw_try_lock_shared<br>
 | |
| pthread_mutex_unlock<br>
 | |
| pthread_rwlock_unlock<br>
 | |
| lck_mtx_unlock<br>
 | |
| lck_rw_done</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| pthread_mutex_t mtx;
 | |
| 
 | |
| void test() {
 | |
|   pthread_mutex_lock(&mtx);
 | |
|   pthread_mutex_lock(&mtx); 
 | |
|     // warn: this lock has already been acquired
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| lck_mtx_t lck1, lck2;
 | |
| 
 | |
| void test() {
 | |
|   lck_mtx_lock(&lck1);
 | |
|   lck_mtx_lock(&lck2);
 | |
|   lck_mtx_unlock(&lck1); 
 | |
|     // warn: this was not the most recently acquired lock
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| lck_mtx_t lck1, lck2;
 | |
| 
 | |
| void test() {
 | |
|   if (lck_mtx_try_lock(&lck1) == 0)
 | |
|     return;
 | |
| 
 | |
|   lck_mtx_lock(&lck2);
 | |
|   lck_mtx_unlock(&lck1);
 | |
|     // warn: this was not the most recently acquired lock
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.SimpleStream</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for misuses of stream APIs:<div class=functions>
 | |
| fopen<br>
 | |
| fclose</div>(demo checker, the subject of the demo
 | |
| (<a href="http://llvm.org/devmtg/2012-11/Zaks-Rose-Checker24Hours.pdf">Slides</a>
 | |
| ,<a href="http://llvm.org/devmtg/2012-11/videos/Zaks-Rose-Checker24Hours.mp4">Video</a>) 
 | |
| by Anna Zaks and Jordan Rose presented at the <a href="http://llvm.org/devmtg/2012-11/">
 | |
| 2012 LLVM Developers' Meeting).</a></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   FILE *F = fopen("myfile.txt", "w");
 | |
| } // warn: opened file is never closed
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   FILE *F = fopen("myfile.txt", "w");
 | |
| 
 | |
|   if (F)
 | |
|     fclose(F);
 | |
| 
 | |
|   fclose(F); // warn: closing a previously closed file stream
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.Stream</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check stream handling functions:<div class=functions>fopen<br>
 | |
| tmpfile<br>
 | |
| fclose<br>
 | |
| fread<br>
 | |
| fwrite<br>
 | |
| fseek<br>
 | |
| ftell<br>
 | |
| rewind<br>
 | |
| fgetpos<br>
 | |
| fsetpos<br>
 | |
| clearerr<br>
 | |
| feof<br>
 | |
| ferror<br>
 | |
| fileno</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   FILE *p = fopen("foo", "r");
 | |
| } // warn: opened file is never closed
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   FILE *p = fopen("foo", "r");
 | |
|   fseek(p, 1, SEEK_SET); // warn: stream pointer might be NULL
 | |
|   fclose(p); 
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   FILE *p = fopen("foo", "r");
 | |
| 
 | |
|   if (p)
 | |
|     fseek(p, 1, 3);
 | |
|      // warn: third arg should be SEEK_SET, SEEK_END, or SEEK_CUR
 | |
| 
 | |
|   fclose(p); 
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   FILE *p = fopen("foo", "r");
 | |
|   fclose(p); 
 | |
|   fclose(p); // warn: already closed
 | |
| }
 | |
| </pre></div><div class="separator"></div>
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   FILE *p = tmpfile();
 | |
|   ftell(p); // warn: stream pointer might be NULL
 | |
|   fclose(p);
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.cstring.BufferOverlap</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Checks for overlap in two buffer arguments; applies to:<div class=functions>
 | |
| memcpy<br>
 | |
| mempcpy</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int a[4] = {0};
 | |
|   memcpy(a + 2, a + 1, 8); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.cstring.NotNullTerminated</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for arguments which are not null-terminated strings; applies
 | |
| to:<div class=functions>
 | |
| strlen<br>
 | |
| strnlen<br>
 | |
| strcpy<br>
 | |
| strncpy<br>
 | |
| strcat<br>
 | |
| strncat</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test() {
 | |
|   int y = strlen((char *)&test); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| 
 | |
| <tr><td><div class="namedescr expandable"><span class="name">
 | |
| alpha.unix.cstring.OutOfBounds</span><span class="lang">
 | |
| (C)</span><div class="descr">
 | |
| Check for out-of-bounds access in string functions; applies
 | |
| to:<div class=functions>
 | |
| strncopy<br>
 | |
| strncat</div></div></div></td>
 | |
| <td><div class="exampleContainer expandable">
 | |
| <div class="example"><pre>
 | |
| void test(char *y) {
 | |
|   char x[4];
 | |
|   if (strlen(y) == 4)
 | |
|     strncpy(x, y, 5); // warn
 | |
| }
 | |
| </pre></div></div></td></tr>
 | |
| 
 | |
| </tbody></table>
 | |
| 
 | |
| </div> <!-- page -->
 | |
| </div> <!-- content -->
 | |
| </body>
 | |
| </html>
 |