keychainAPI.m revision 62a811d171fd16cb45b4617be40d10aec8578c07
1// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.osx.KeychainAPI %s -verify 2 3// Fake typedefs. 4typedef unsigned int OSStatus; 5typedef unsigned int SecKeychainAttributeList; 6typedef unsigned int SecKeychainItemRef; 7typedef unsigned int SecItemClass; 8typedef unsigned int UInt32; 9typedef unsigned int CFTypeRef; 10typedef unsigned int UInt16; 11typedef unsigned int SecProtocolType; 12typedef unsigned int SecAuthenticationType; 13typedef unsigned int SecKeychainAttributeInfo; 14enum { 15 noErr = 0, 16 GenericError = 1 17}; 18 19// Functions that allocate data. 20OSStatus SecKeychainItemCopyContent ( 21 SecKeychainItemRef itemRef, 22 SecItemClass *itemClass, 23 SecKeychainAttributeList *attrList, 24 UInt32 *length, 25 void **outData 26); 27OSStatus SecKeychainFindGenericPassword ( 28 CFTypeRef keychainOrArray, 29 UInt32 serviceNameLength, 30 const char *serviceName, 31 UInt32 accountNameLength, 32 const char *accountName, 33 UInt32 *passwordLength, 34 void **passwordData, 35 SecKeychainItemRef *itemRef 36); 37OSStatus SecKeychainFindInternetPassword ( 38 CFTypeRef keychainOrArray, 39 UInt32 serverNameLength, 40 const char *serverName, 41 UInt32 securityDomainLength, 42 const char *securityDomain, 43 UInt32 accountNameLength, 44 const char *accountName, 45 UInt32 pathLength, 46 const char *path, 47 UInt16 port, 48 SecProtocolType protocol, 49 SecAuthenticationType authenticationType, 50 UInt32 *passwordLength, 51 void **passwordData, 52 SecKeychainItemRef *itemRef 53); 54OSStatus SecKeychainItemCopyAttributesAndData ( 55 SecKeychainItemRef itemRef, 56 SecKeychainAttributeInfo *info, 57 SecItemClass *itemClass, 58 SecKeychainAttributeList **attrList, 59 UInt32 *length, 60 void **outData 61); 62 63// Functions which free data. 64OSStatus SecKeychainItemFreeContent ( 65 SecKeychainAttributeList *attrList, 66 void *data 67); 68OSStatus SecKeychainItemFreeAttributesAndData ( 69 SecKeychainAttributeList *attrList, 70 void *data 71); 72 73void errRetVal() { 74 unsigned int *ptr = 0; 75 OSStatus st = 0; 76 UInt32 length; 77 void *outData; 78 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 79 if (st == GenericError) // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'.}} 80 SecKeychainItemFreeContent(ptr, outData); // expected-warning{{Trying to free data which has not been allocated.}} 81} 82 83// If null is passed in, the data is not allocated, so no need for the matching free. 84void fooDoNotReportNull() { 85 unsigned int *ptr = 0; 86 OSStatus st = 0; 87 UInt32 *length = 0; 88 void **outData = 0; 89 SecKeychainItemCopyContent(2, ptr, ptr, 0, 0); 90 SecKeychainItemCopyContent(2, ptr, ptr, length, outData); 91}// no-warning 92 93void doubleAlloc() { 94 unsigned int *ptr = 0; 95 OSStatus st = 0; 96 UInt32 *length = 0; 97 void **outData = 0; 98 SecKeychainItemCopyContent(2, ptr, ptr, length, outData); 99 SecKeychainItemCopyContent(2, ptr, ptr, length, outData); 100}// no-warning 101 102void fooOnlyFree() { 103 unsigned int *ptr = 0; 104 OSStatus st = 0; 105 UInt32 length; 106 void *outData = &length; 107 SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}} 108} 109 110// Do not warn if undefined value is passed to a function. 111void fooOnlyFreeUndef() { 112 unsigned int *ptr = 0; 113 OSStatus st = 0; 114 UInt32 length; 115 void *outData; 116 SecKeychainItemFreeContent(ptr, outData); 117}// no-warning 118 119// Do not warn if the address is a parameter in the enclosing function. 120void fooOnlyFreeParam(void *attrList, void* X) { 121 SecKeychainItemFreeContent(attrList, X); 122}// no-warning 123 124// If we are returning the value, no not report. 125void* returnContent() { 126 unsigned int *ptr = 0; 127 OSStatus st = 0; 128 UInt32 length; 129 void *outData; 130 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 131 return outData; 132} // no-warning 133 134int apiMismatch(SecKeychainItemRef itemRef, 135 SecKeychainAttributeInfo *info, 136 SecItemClass *itemClass) { 137 OSStatus st = 0; 138 SecKeychainAttributeList *attrList; 139 UInt32 length; 140 void *outData; 141 142 st = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 143 &attrList, &length, &outData); 144 if (st == noErr) 145 SecKeychainItemFreeContent(attrList, outData); // expected-warning{{Allocator doesn't match the deallocator}} 146 return 0; 147} 148 149int ErrorCodesFromDifferentAPISDoNotInterfere(SecKeychainItemRef itemRef, 150 SecKeychainAttributeInfo *info, 151 SecItemClass *itemClass) { 152 unsigned int *ptr = 0; 153 OSStatus st = 0; 154 UInt32 length; 155 void *outData; 156 OSStatus st2 = 0; 157 SecKeychainAttributeList *attrList; 158 UInt32 length2; 159 void *outData2; 160 161 st2 = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 162 &attrList, &length2, &outData2); 163 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 164 if (st == noErr) { 165 SecKeychainItemFreeContent(ptr, outData); 166 if (st2 == noErr) { 167 SecKeychainItemFreeAttributesAndData(attrList, outData2); 168 } 169 } 170 return 0; // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeAttributesAndData'}} 171} 172 173int foo() { 174 unsigned int *ptr = 0; 175 OSStatus st = 0; 176 177 UInt32 length; 178 void *outData; 179 180 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); 181 if (st == noErr) 182 SecKeychainItemFreeContent(ptr, outData); 183 184 return 0; 185}// no-warning 186