brintos

brintos / llvm-project-archived public Read only

0
0
Text · 14.5 KiB · f72bc78 Raw
469 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=osx.SecKeychainAPI -fblocks %s -verify2 3#include "Inputs/system-header-simulator-objc.h"4 5// Fake typedefs.6typedef unsigned int OSStatus;7typedef unsigned int SecKeychainAttributeList;8typedef unsigned int SecKeychainItemRef;9typedef unsigned int SecItemClass;10typedef unsigned int UInt32;11typedef unsigned int SecProtocolType;12typedef unsigned int SecAuthenticationType;13typedef unsigned int SecKeychainAttributeInfo;14enum {15  noErr                      = 0,16  GenericError               = 117};18 19// Functions that allocate data.20OSStatus SecKeychainItemCopyContent (21    SecKeychainItemRef itemRef,22    SecItemClass *itemClass,23    SecKeychainAttributeList *attrList,24    UInt32 *length,25    void **outData26);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 *itemRef36);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 *itemRef53);54OSStatus SecKeychainItemCopyAttributesAndData (55   SecKeychainItemRef itemRef,56   SecKeychainAttributeInfo *info,57   SecItemClass *itemClass,58   SecKeychainAttributeList **attrList,59   UInt32 *length,60   void **outData61);62 63// Functions which free data.64OSStatus SecKeychainItemFreeContent (65    SecKeychainAttributeList *attrList,66    void *data67);68OSStatus SecKeychainItemFreeAttributesAndData (69   SecKeychainAttributeList *attrList,70   void *data71);72 73void errRetVal(void) {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)80    SecKeychainItemFreeContent(ptr, outData);81} // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}82 83// If null is passed in, the data is not allocated, so no need for the matching free.84void fooDoNotReportNull(void) {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-warning92 93void doubleAlloc(void) {94    unsigned int *ptr = 0;95    OSStatus st = 0;96    UInt32 length;97    void *outData;98    st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);99    st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData); // expected-warning {{Allocated data should be released before another call to the allocator:}}100    if (st == noErr)101      SecKeychainItemFreeContent(ptr, outData);102}103 104// Do not warn if undefined value is passed to a function.105void fooOnlyFreeUndef(void) {106  unsigned int *ptr = 0;107  OSStatus st = 0;108  UInt32 length;109  void *outData;110  SecKeychainItemFreeContent(ptr, outData);111}// no-warning112 113// Do not warn if the address is a parameter in the enclosing function.114void fooOnlyFreeParam(void *attrList, void* X) {115    SecKeychainItemFreeContent(attrList, X); 116}// no-warning117 118// If we are returning the value, do not report.119void* returnContent(void) {120  unsigned int *ptr = 0;121  OSStatus st = 0;122  UInt32 length;123  void *outData;124  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);125  return outData;126} // no-warning127 128// Password was passed in as an argument and does not have to be deleted.129OSStatus getPasswordAndItem(void** password, UInt32* passwordLength) {130  OSStatus err;131  SecKeychainItemRef item;132  err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx",133                                       passwordLength, password, &item);134  return err;135} // no-warning136 137// Make sure we do not report an error if we call free only if password != 0.138// Also, do not report double allocation if first allocation returned an error.139OSStatus testSecKeychainFindGenericPassword(UInt32* passwordLength,140                        CFTypeRef keychainOrArray, SecProtocolType protocol, 141                        SecAuthenticationType authenticationType) {142  OSStatus err;143  SecKeychainItemRef item;144  void *password;145  err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx",146                                       passwordLength, &password, &item);147  if( err == GenericError ) {148    err = SecKeychainFindInternetPassword(keychainOrArray, 149                                  16, "server", 16, "domain", 16, "account",150                                  16, "path", 222, protocol, authenticationType,151                                  passwordLength, &(password), 0);152  }153 154  if (err == noErr && password) {155    SecKeychainItemFreeContent(0, password);156  }157  return err;158}159 160int apiMismatch(SecKeychainItemRef itemRef, 161         SecKeychainAttributeInfo *info,162         SecItemClass *itemClass) {163  OSStatus st = 0;164  SecKeychainAttributeList *attrList;165  UInt32 length;166  void *outData;167  168  st = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 169                                            &attrList, &length, &outData); 170  if (st == noErr)171    SecKeychainItemFreeContent(attrList, outData); // expected-warning{{Deallocator doesn't match the allocator}}172  return 0;173}174 175int ErrorCodesFromDifferentAPISDoNotInterfere(SecKeychainItemRef itemRef, 176                                              SecKeychainAttributeInfo *info,177                                              SecItemClass *itemClass) {178  unsigned int *ptr = 0;179  OSStatus st = 0;180  UInt32 length;181  void *outData;182  OSStatus st2 = 0;183  SecKeychainAttributeList *attrList;184  UInt32 length2;185  void *outData2;186 187  st2 = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass, 188                                             &attrList, &length2, &outData2);189  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);  190  if (st == noErr) {191    SecKeychainItemFreeContent(ptr, outData);192    if (st2 == noErr) {193      SecKeychainItemFreeAttributesAndData(attrList, outData2);194    }195  } 196  return 0; // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeAttributesAndData'}}197}198 199int foo(CFTypeRef keychainOrArray, SecProtocolType protocol, 200        SecAuthenticationType authenticationType, SecKeychainItemRef *itemRef) {201  unsigned int *ptr = 0;202  OSStatus st = 0;203 204  UInt32 length;205  void *outData[5];206 207  st = SecKeychainFindInternetPassword(keychainOrArray, 208                                       16, "server", 16, "domain", 16, "account",209                                       16, "path", 222, protocol, authenticationType,210                                       &length, &(outData[3]), itemRef);211  if (length == 5) {212    if (st == noErr)213      SecKeychainItemFreeContent(ptr, outData[3]);214  }215  if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'}}216    length++;217  }218  return 0;219}220 221int testErrorCodeAsLHS(CFTypeRef keychainOrArray, SecProtocolType protocol,222        SecAuthenticationType authenticationType, SecKeychainItemRef *itemRef) {223  unsigned int *ptr = 0;224  OSStatus st = 0;225  UInt32 length;226  void *outData;227  st = SecKeychainFindInternetPassword(keychainOrArray,228                                       16, "server", 16, "domain", 16, "account",229                                       16, "path", 222, protocol, authenticationType,230                                       &length, &outData, itemRef);231  if (noErr == st)232    SecKeychainItemFreeContent(ptr, outData);233 234  return 0;235}236 237void free(void *ptr);238void deallocateWithFree(void) {239    unsigned int *ptr = 0;240    OSStatus st = 0;241    UInt32 length;242    void *outData;243    st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);244    if (st == noErr)245      free(outData); // expected-warning{{Deallocator doesn't match the allocator: 'SecKeychainItemFreeContent' should be used}}246}247 248// Typesdefs for CFStringCreateWithBytesNoCopy.249typedef char uint8_t;250typedef signed long CFIndex;251typedef UInt32 CFStringEncoding;252typedef unsigned Boolean;253typedef const struct __CFString * CFStringRef;254typedef const struct __CFAllocator * CFAllocatorRef;255extern const CFAllocatorRef kCFAllocatorDefault;256extern const CFAllocatorRef kCFAllocatorSystemDefault;257extern const CFAllocatorRef kCFAllocatorMalloc;258extern const CFAllocatorRef kCFAllocatorMallocZone;259extern const CFAllocatorRef kCFAllocatorNull;260extern const CFAllocatorRef kCFAllocatorUseContext;261CFStringRef CFStringCreateWithBytesNoCopy(CFAllocatorRef alloc, const uint8_t *bytes, CFIndex numBytes, CFStringEncoding encoding, Boolean externalFormat, CFAllocatorRef contentsDeallocator);262 263void DellocWithCFStringCreate1(CFAllocatorRef alloc) {264  unsigned int *ptr = 0;265  OSStatus st = 0;266  UInt32 length;267  void *bytes;268  char * x;269  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes);270  if (st == noErr) {271    CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorDefault); // expected-warning{{Deallocator doesn't match the allocator:}} 272    CFRelease(userStr);273  }274}275 276void DellocWithCFStringCreate2(CFAllocatorRef alloc) {277  unsigned int *ptr = 0;278  OSStatus st = 0;279  UInt32 length;280  void *bytes;281  char * x;282  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes);283  if (st == noErr) {284    CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorNull); // expected-warning{{Allocated data is not released}}285    CFRelease(userStr); 286  }287}288 289void DellocWithCFStringCreate3(CFAllocatorRef alloc) {290  unsigned int *ptr = 0;291  OSStatus st = 0;292  UInt32 length;293  void *bytes;294  char * x;295  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes);296  if (st == noErr) {297    CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, kCFAllocatorUseContext);298    CFRelease(userStr);299  }300}301 302void DellocWithCFStringCreate4(CFAllocatorRef alloc) {303  unsigned int *ptr = 0;304  OSStatus st = 0;305  UInt32 length;306  void *bytes;307  char * x;308  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes);309  if (st == noErr) {310    CFStringRef userStr = CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, 0); // expected-warning{{Deallocator doesn't match the allocator:}} 311    CFRelease(userStr);312  }313}314 315static CFAllocatorRef gKeychainDeallocator = 0;316 317static CFAllocatorRef GetKeychainDeallocator(void) {  318  return gKeychainDeallocator;319}320 321CFStringRef DellocWithCFStringCreate5(CFAllocatorRef alloc) {322  unsigned int *ptr = 0;323  OSStatus st = 0;324  UInt32 length;325  void *bytes;326  char * x;327  st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &bytes);328  if (st == noErr) {329    return CFStringCreateWithBytesNoCopy(alloc, bytes, length, 5, 0, GetKeychainDeallocator()); // no-warning330  }331  return 0;332}333 334void radar10508828(void) {335  UInt32 pwdLen = 0;336  void*  pwdBytes = 0;337  OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0);338#pragma unused(rc)339  if (pwdBytes)340    SecKeychainItemFreeContent(0, pwdBytes);341}342 343void radar10508828_20092614(void) {344  UInt32 pwdLen = 0;345  void*  pwdBytes = 0;346  OSStatus rc = SecKeychainFindGenericPassword(0, 3, "foo", 3, "bar", &pwdLen, &pwdBytes, 0);347  SecKeychainItemFreeContent(0, pwdBytes);348}349 350//Example from bug 10797.351__inline__ static352const char *__WBASLLevelString(int level) {353  return "foo";354}355 356static int *bug10798(int *p, int columns, int prevRow) {357  int *row = 0;358  row = p + prevRow * columns;359  prevRow += 2;360  do {361    ++prevRow;362    row+=columns;363  } while(10 >= row[1]);364  return row;365}366 367// Test inter-procedural behaviour.368 369void my_FreeParam(void *attrList, void* X) {370    SecKeychainItemFreeContent(attrList, X); 371}372 373void *my_AllocateReturn(OSStatus *st) {374  unsigned int *ptr = 0;375  UInt32 length;376  void *outData;377  *st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);378  return outData;379}380 381OSStatus my_Allocate_Param(void** password, UInt32* passwordLength) {382  OSStatus err;383  SecKeychainItemRef item;384  err = SecKeychainFindGenericPassword(0, 3, "xx", 3, "xx",385                                       passwordLength, password, &item);386  return err;387}388 389void allocAndFree1(void) {390    unsigned int *ptr = 0;391    OSStatus st = 0;392    UInt32 length;393    void *outData;394    st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);395    if (st == noErr)396      my_FreeParam(ptr, outData);397}398 399void consumeChar(char);400 401void allocNoFree2(int x) {402    OSStatus st = 0;403    void *outData = my_AllocateReturn(&st); 404    if (x) {405      consumeChar(*(char*)outData); // expected-warning{{Allocated data is not released:}}406      return;407    } else {408      consumeChar(*(char*)outData);409    }410    return;411}412 413void allocAndFree2(void *attrList) {414    OSStatus st = 0;415    void *outData = my_AllocateReturn(&st);416    if (st == noErr)417      my_FreeParam(attrList, outData);418}419 420void allocNoFree3(void) {421    UInt32 length = 32;422    void *outData;    423    void *outData2;424    OSStatus st = my_Allocate_Param(&outData, &length); // expected-warning{{Allocated data is not released}}425    st = my_Allocate_Param(&outData2, &length); // expected-warning{{Allocated data is not released}}426}427 428void allocAndFree3(void *attrList) {429    UInt32 length = 32;430    void *outData;431    OSStatus st = my_Allocate_Param(&outData, &length); 432    if (st == noErr)433      SecKeychainItemFreeContent(attrList, outData);434}435 436typedef struct AuthorizationValue {437    int length;438    void *data;439} AuthorizationValue;440typedef struct AuthorizationCallback {441    OSStatus (*SetContextVal)(AuthorizationValue *inValue);442} AuthorizationCallback;443static AuthorizationCallback cb;444int radar_19196494(void) {445  @autoreleasepool {446    AuthorizationValue login_password = {};447    UInt32 passwordLength;448    void *passwordData = 0;449    OSStatus err = SecKeychainFindGenericPassword(0, 0, "", 0, "", (UInt32 *)&login_password.length, (void**)&login_password.data, 0);450    cb.SetContextVal(&login_password);451    if (err == noErr) {452      SecKeychainItemFreeContent(0, login_password.data);453    }454  }455  return 0;456}457int radar_19196494_v2(void) {458  @autoreleasepool {459    AuthorizationValue login_password = {};460    OSStatus err = SecKeychainFindGenericPassword(0, 0, "", 0, "", (UInt32 *)&login_password.length, (void**)&login_password.data, 0);461    if (!login_password.data) return 0;462    cb.SetContextVal(&login_password);463    if (err == noErr) {464      SecKeychainItemFreeContent(0, login_password.data);465    }466  }467  return 0;468}469