blob: af0258a59b2d45ef1d87ab8555554ae1c119ead0 [file] [log] [blame]
Ted Kremenek033a07e2011-08-03 23:14:55 +00001// RUN: %clang_cc1 -analyze -analyzer-checker=experimental.osx.KeychainAPI %s -verify
Anna Zaksf57be282011-08-01 22:40:01 +00002
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;
Anna Zaks62a811d2011-08-04 22:40:38 +000013typedef unsigned int SecKeychainAttributeInfo;
Anna Zaksf57be282011-08-01 22:40:01 +000014enum {
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);
Anna Zaks62a811d2011-08-04 22:40:38 +000054OSStatus SecKeychainItemCopyAttributesAndData (
55 SecKeychainItemRef itemRef,
56 SecKeychainAttributeInfo *info,
57 SecItemClass *itemClass,
58 SecKeychainAttributeList **attrList,
59 UInt32 *length,
60 void **outData
61);
Anna Zaksf57be282011-08-01 22:40:01 +000062
Anna Zaks62a811d2011-08-04 22:40:38 +000063// Functions which free data.
Anna Zaksf57be282011-08-01 22:40:01 +000064OSStatus SecKeychainItemFreeContent (
65 SecKeychainAttributeList *attrList,
66 void *data
67);
Anna Zaks62a811d2011-08-04 22:40:38 +000068OSStatus SecKeychainItemFreeAttributesAndData (
69 SecKeychainAttributeList *attrList,
70 void *data
71);
Anna Zaksf57be282011-08-01 22:40:01 +000072
Anna Zaks03826aa2011-08-04 00:26:57 +000073void errRetVal() {
74 unsigned int *ptr = 0;
75 OSStatus st = 0;
76 UInt32 length;
77 void *outData;
78 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
Anna Zaks62a811d2011-08-04 22:40:38 +000079 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.}}
Anna Zaks03826aa2011-08-04 00:26:57 +000081}
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
Anna Zaks62a811d2011-08-04 22:40:38 +000093void 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
Anna Zaks03826aa2011-08-04 00:26:57 +0000102void 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.
Anna Zaks62a811d2011-08-04 22:40:38 +0000120void fooOnlyFreeParam(void *attrList, void* X) {
121 SecKeychainItemFreeContent(attrList, X);
Anna Zaks03826aa2011-08-04 00:26:57 +0000122}// 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
Anna Zaks62a811d2011-08-04 22:40:38 +0000134int 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() {
Anna Zaksf57be282011-08-01 22:40:01 +0000174 unsigned int *ptr = 0;
175 OSStatus st = 0;
176
177 UInt32 length;
178 void *outData;
179
180 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
Anna Zakse68b5f12011-08-02 17:11:03 +0000181 if (st == noErr)
182 SecKeychainItemFreeContent(ptr, outData);
Anna Zaksf57be282011-08-01 22:40:01 +0000183
184 return 0;
Anna Zaks03826aa2011-08-04 00:26:57 +0000185}// no-warning