Bug Summary

File:src/usr.bin/keynote/../../lib/libkeynote/keynote-verify.c
Warning:line 184, column 11
Result of 'calloc' is converted to a pointer of type 'char *', which is incompatible with sizeof operand type 'char **'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.0 -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name keynote-verify.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 1 -pic-is-pie -mframe-pointer=all -relaxed-aliasing -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -target-feature +retpoline-indirect-calls -target-feature +retpoline-indirect-branches -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/usr/src/usr.bin/keynote/obj -resource-dir /usr/local/lib/clang/13.0.0 -I . -I /usr/src/usr.bin/keynote -I /usr/src/usr.bin/keynote/../../lib/libkeynote -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.bin/keynote/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -fno-builtin-malloc -fno-builtin-calloc -fno-builtin-realloc -fno-builtin-valloc -fno-builtin-free -fno-builtin-strdup -fno-builtin-strndup -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/ben/Projects/vmm/scan-build/2022-01-12-194120-40624-1 -x c /usr/src/usr.bin/keynote/../../lib/libkeynote/keynote-verify.c
1/* $OpenBSD: keynote-verify.c,v 1.20 2021/10/24 21:24:20 deraadt Exp $ */
2/*
3 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu)
4 *
5 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA,
6 * in April-May 1998
7 *
8 * Copyright (C) 1998, 1999 by Angelos D. Keromytis.
9 *
10 * Permission to use, copy, and modify this software with or without fee
11 * is hereby granted, provided that this entire notice is included in
12 * all copies of any software which is or includes a copy or
13 * modification of this software.
14 *
15 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
16 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO
17 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
18 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
19 * PURPOSE.
20 */
21
22#include <sys/types.h>
23#include <sys/stat.h>
24
25#include <ctype.h>
26#include <fcntl.h>
27#include <getopt.h>
28#include <regex.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33
34#include "header.h"
35#include "keynote.h"
36
37int sessid;
38
39void verifyusage(void);
40
41void
42verifyusage(void)
43{
44 fprintf(stderr(&__sF[2]), "Arguments:\n");
45 fprintf(stderr(&__sF[2]), "\t-h: This message\n");
46 fprintf(stderr(&__sF[2]),
47 "\t-r <valuelist>: Comma separated, ordered return-value list\n");
48 fprintf(stderr(&__sF[2]), "\t-e <filename>: Environment settings\n");
49 fprintf(stderr(&__sF[2]), "\t-l <filename>: Trusted (local) assertion\n");
50 fprintf(stderr(&__sF[2]), "\t-k <filename>: File containing key\n");
51 fprintf(stderr(&__sF[2]), "Followed by a list of:\n");
52 fprintf(stderr(&__sF[2]), "\t<filename>: Non-local assertion\n");
53}
54
55void
56keynote_verify(int argc, char *argv[])
57{
58 int fd, i, ch, se = 0, cl = 8192, sk = 0, sl = 0, p, ac = argc;
59 char *buf, **av = argv, **retv, **foov, *ptr;
60 int numretv = 16, numret = 0, sn;
61 struct stat sb;
62
63 if (argc == 1)
64 {
65 verifyusage();
66 exit(1);
67 }
68
69 if ((buf = calloc(cl, sizeof(char))) == NULL((void *)0))
70 {
71 perror("calloc()");
72 exit(1);
73 }
74
75 if ((retv = calloc(numretv, sizeof(char *))) == NULL((void *)0))
76 {
77 perror("calloc()");
78 exit(1);
79 }
80
81 /* "ac" and "av" are used for stress-testing, ignore otherwise */
82 argv = av;
83 argc = ac;
84 sn = 0;
85 opterr = 0;
86
87 sessid = kn_init();
88 if (sessid == -1)
89 {
90 fprintf(stderr(&__sF[2]), "kn_init() failed (errno %d).\n", keynote_errno);
91 exit(keynote_errno);
92 }
93
94 while ((ch = getopt(argc, argv, "hqistl:e:k:r:")) != -1)
95 {
96 switch (ch)
97 {
98 case 'e':
99 if (read_environment(optarg) == -1)
100 exit(1);
101 se = 1;
102 break;
103
104 case 'k':
105 sk = 1;
106
107 if ((fd = open(optarg, O_RDONLY0x0000)) == -1)
108 {
109 perror(optarg);
110 exit(1);
111 }
112
113 if (fstat(fd, &sb) == -1)
114 {
115 perror("fstat()");
116 exit(1);
117 }
118
119 if (sb.st_size > cl - 1)
120 {
121 free(buf);
122 cl = sb.st_size + 1;
123 buf = calloc(cl, sizeof(char));
124 if (buf == NULL((void *)0))
125 {
126 perror("calloc()");
127 exit(1);
128 }
129 }
130
131 i = read(fd, buf, sb.st_size);
132 if (i == -1)
133 {
134 perror("read()");
135 exit(1);
136 }
137
138 close(fd);
139
140 parse_key(buf);
141 switch (keynote_errno)
142 {
143 case 0: /* No errors */
144 break;
145
146 case ERROR_SYNTAX-2:
147 fprintf(stderr(&__sF[2]), "Syntax error adding authorizer "
148 "%s\n", optarg);
149 exit(1);
150
151 case ERROR_MEMORY-1:
152 perror("Out of memory.\n");
153 exit(1);
154
155 default:
156 fprintf(stderr(&__sF[2]), "Unknown error (%d).\n",
157 keynote_errno);
158 }
159
160 break;
161
162 case 'h':
163 verifyusage();
164 exit(0);
165
166 case 'r':
167 if (sn != 0)
168 {
169 fprintf(stderr(&__sF[2]),
170 "Do not define two sets of return values.\n");
171 exit(1);
172 }
173
174 sn = 1;
175
176 for (numret = 0;
177 (ptr = strchr(optarg, ',')) != NULL((void *)0);
178 numret++)
179 {
180 /* Running out of memory */
181 if (numret > numretv - 3)
182 {
183 numretv *= 2;
184 foov = calloc(numretv, sizeof(char **));
Result of 'calloc' is converted to a pointer of type 'char *', which is incompatible with sizeof operand type 'char **'
185 if (foov == NULL((void *)0))
186 {
187 /*
188 * If this were a real program, we 'd be freeing
189 * retv here. Since we're exiting, we can be a
190 * little sloppy.
191 */
192 perror("calloc()");
193 exit(1);
194 }
195
196 memcpy(foov, retv, numretv * sizeof(char **));
197 free(retv);
198 retv = foov;
199 }
200
201 retv[numret] = calloc((ptr - optarg) + 1,
202 sizeof(char));
203 if (retv[numret] == NULL((void *)0))
204 {
205 /* Comment from above applies here as well */
206 perror("calloc()");
207 exit(1);
208 }
209
210 /* Copy */
211 memcpy(retv[numret], optarg, ptr - optarg);
212 optarg = ptr + 1;
213 }
214
215 /* Last component */
216 retv[numret] = strdup(optarg);
217 if (retv[numret] == NULL((void *)0))
218 {
219 perror("calloc()");
220 exit(1);
221 }
222
223 numret++;
224 break;
225
226 case 'l':
227 if ((fd = open(optarg, O_RDONLY0x0000)) == -1)
228 {
229 perror(optarg);
230 exit(1);
231 }
232
233 if (fstat(fd, &sb) == -1)
234 {
235 perror("fstat()");
236 exit(1);
237 }
238
239 if (sb.st_size > cl - 1)
240 {
241 free(buf);
242 cl = sb.st_size + 1;
243 buf = calloc(cl, sizeof(char));
244 if (buf == NULL((void *)0))
245 {
246 perror("calloc()");
247 exit(1);
248 }
249 }
250
251 i = read(fd, buf, sb.st_size);
252 if (i == -1)
253 {
254 perror("read()");
255 exit(1);
256 }
257
258 close(fd);
259 p = kn_add_assertion(sessid, buf, i, ASSERT_FLAG_LOCAL0x0001);
260 if (p == -1)
261 {
262 fprintf(stderr(&__sF[2]),
263 "Error for assertion in file <%s>, errno %d.\n",
264 optarg, keynote_errno);
265 keynote_errno = 0;
266 }
267
268 memset(buf, 0, sb.st_size);
269 sl = 1;
270 break;
271
272 case '?':
273 default:
274 verifyusage();
275 exit(1);
276 }
277 }
278
279 argc -= optind;
280 argv += optind;
281 optind = 1;
282
283 if (sn == 0)
284 {
285 fprintf(stderr(&__sF[2]),
286 "Should set return values before evaluations begin.\n");
287 exit(1);
288 }
289
290 if (se == 0)
291 {
292 fprintf(stderr(&__sF[2]), "Should set environment before evaluations begin.\n");
293 exit(1);
294 }
295
296 if (sk == 0)
297 {
298 fprintf(stderr(&__sF[2]), "Should specify at least one action authorizer.\n");
299 exit(1);
300 }
301
302 if (sl == 0)
303 {
304 fprintf(stderr(&__sF[2]),
305 "Should specify at least one trusted assertion (POLICY).\n");
306 exit(1);
307 }
308
309 while (argc--)
310 {
311 if ((fd = open(argv[argc], O_RDONLY0x0000)) == -1)
312 {
313 perror(argv[argc]);
314 exit(1);
315 }
316
317 if (fstat(fd, &sb) == -1)
318 {
319 perror("fstat()");
320 exit(1);
321 }
322
323 if (sb.st_size > cl - 1)
324 {
325 free(buf);
326 cl = sb.st_size + 1;
327 buf = calloc(cl, sizeof(char));
328 if (buf == NULL((void *)0))
329 {
330 perror("calloc()");
331 exit(1);
332 }
333 }
334
335 i = read(fd, buf, sb.st_size);
336 if (i == -1)
337 {
338 perror("read()");
339 exit(1);
340 }
341
342 close(fd);
343 p = kn_add_assertion(sessid, buf, i, 0);
344 if (p == -1)
345 {
346 fprintf(stderr(&__sF[2]), "Error for assertion in file <%s>, errno %d.\n",
347 argv[argc], keynote_errno);
348 keynote_errno = 0;
349 }
350
351 memset(buf, 0, sb.st_size);
352 }
353
354 p = kn_do_query(sessid, retv, numret); /* Evaluation time */
355
356 printf("Query result = ");
357
358 switch (keynote_errno)
359 {
360 case ERROR_MEMORY-1:
361 printf("<out of memory>\n");
362 exit(1);
363
364 case ERROR_SYNTAX-2:
365 printf("<uninitialized authorizers or all POLICY "
366 "assertions are malformed!>\n");
367 exit(1);
368
369 case ERROR_NOTFOUND-3:
370 printf("<session or other information not found!>\n");
371 exit(1);
372
373 case 0: /* No errors */
374 break;
375
376 default:
377 printf("<should never happen (%d)!>\n", keynote_errno);
378 exit(1);
379 }
380
381 printf("%s\n", retv[p]);
382
383 keynote_errno = 0;
384
385 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_MEMORY2, 0)) != -1)
386 {
387 printf("Failed assertion %d due to memory error.\n", i);
388 kn_remove_assertion(sessid, i);
389 }
390
391 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_SYNTAX1, 0)) != -1)
392 {
393 printf("Failed assertion %d due to syntax or semantic error.\n", i);
394 kn_remove_assertion(sessid, i);
395 }
396
397 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_SIGNATURE3, 0)) != -1)
398 {
399 printf("Failed assertion %d due to signature verification failure.\n",
400 i);
401 kn_remove_assertion(sessid, i);
402 }
403
404 while ((i = kn_get_failed(sessid, KEYNOTE_ERROR_ANY0, 0)) != -1)
405 {
406 printf("Failed assertion %d due to unspecified error.\n", i);
407 kn_remove_assertion(sessid, i);
408 }
409
410 kn_close(sessid);
411
412 /* This is a reminder that return values are not free'ed by KeyNote */
413 for (sn = 0; sn < numret; sn++)
414 free(retv[sn]);
415 free(retv);
416 retv = NULL((void *)0);
417
418 exit(0);
419}