blob: 74834ab5d5c65d4f70a06826b9a7ec479091fa55 [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() {
Anna Zaks703ffb12011-08-12 21:56:43 +000074 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{{Call to free data when error was returned during allocation.}}
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;
Anna Zaksca0b57e2011-08-05 00:37:00 +000096 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}
Anna Zaks62a811d2011-08-04 22:40:38 +0000103
Anna Zaks03826aa2011-08-04 00:26:57 +0000104void fooOnlyFree() {
105 unsigned int *ptr = 0;
106 OSStatus st = 0;
107 UInt32 length;
108 void *outData = &length;
109 SecKeychainItemFreeContent(ptr, outData);// expected-warning{{Trying to free data which has not been allocated}}
110}
111
112// Do not warn if undefined value is passed to a function.
113void fooOnlyFreeUndef() {
114 unsigned int *ptr = 0;
115 OSStatus st = 0;
116 UInt32 length;
117 void *outData;
118 SecKeychainItemFreeContent(ptr, outData);
119}// no-warning
120
121// Do not warn if the address is a parameter in the enclosing function.
Anna Zaks62a811d2011-08-04 22:40:38 +0000122void fooOnlyFreeParam(void *attrList, void* X) {
123 SecKeychainItemFreeContent(attrList, X);
Anna Zaks03826aa2011-08-04 00:26:57 +0000124}// no-warning
125
Anna Zaks703ffb12011-08-12 21:56:43 +0000126// If we are returning the value, do not report.
Anna Zaks03826aa2011-08-04 00:26:57 +0000127void* returnContent() {
128 unsigned int *ptr = 0;
129 OSStatus st = 0;
130 UInt32 length;
131 void *outData;
132 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
133 return outData;
134} // no-warning
135
Anna Zaks79c9c752011-08-12 22:47:22 +0000136// Password was passed in as an argument and does nt have to be deleted.
137OSStatus getPasswordAndItem(void** password, UInt32* passwordLength) {
138 OSStatus err;
139 SecKeychainItemRef item;
140 err = SecKeychainFindGenericPassword(0, 3, "xx",
141 3, "xx",
142 passwordLength, password,
143 &item);
144 return err;
145} // no-warning
146
Anna Zaks62a811d2011-08-04 22:40:38 +0000147int apiMismatch(SecKeychainItemRef itemRef,
148 SecKeychainAttributeInfo *info,
149 SecItemClass *itemClass) {
150 OSStatus st = 0;
151 SecKeychainAttributeList *attrList;
152 UInt32 length;
153 void *outData;
154
155 st = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass,
156 &attrList, &length, &outData);
157 if (st == noErr)
158 SecKeychainItemFreeContent(attrList, outData); // expected-warning{{Allocator doesn't match the deallocator}}
159 return 0;
160}
161
162int ErrorCodesFromDifferentAPISDoNotInterfere(SecKeychainItemRef itemRef,
163 SecKeychainAttributeInfo *info,
164 SecItemClass *itemClass) {
165 unsigned int *ptr = 0;
166 OSStatus st = 0;
167 UInt32 length;
168 void *outData;
169 OSStatus st2 = 0;
170 SecKeychainAttributeList *attrList;
171 UInt32 length2;
172 void *outData2;
173
174 st2 = SecKeychainItemCopyAttributesAndData(itemRef, info, itemClass,
175 &attrList, &length2, &outData2);
176 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &outData);
177 if (st == noErr) {
178 SecKeychainItemFreeContent(ptr, outData);
179 if (st2 == noErr) {
180 SecKeychainItemFreeAttributesAndData(attrList, outData2);
181 }
182 }
183 return 0; // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeAttributesAndData'}}
184}
185
186int foo() {
Anna Zaksf57be282011-08-01 22:40:01 +0000187 unsigned int *ptr = 0;
188 OSStatus st = 0;
189
190 UInt32 length;
Anna Zaks703ffb12011-08-12 21:56:43 +0000191 void *outData[5];
Anna Zaksf57be282011-08-01 22:40:01 +0000192
Anna Zaks703ffb12011-08-12 21:56:43 +0000193 st = SecKeychainItemCopyContent(2, ptr, ptr, &length, &(outData[3]));
194 if (length == 5) {
195 if (st == noErr)
196 SecKeychainItemFreeContent(ptr, outData[3]);
197 }
198 if (length) { // expected-warning{{Allocated data is not released: missing a call to 'SecKeychainItemFreeContent'.}}
199 length++;
200 }
Anna Zaksf57be282011-08-01 22:40:01 +0000201 return 0;
Anna Zaks03826aa2011-08-04 00:26:57 +0000202}// no-warning