Bug Summary

File:db/fileutil.c
Warning:line 458, column 6
Attempt to free released memory

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-redhat-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name fileutil.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 2 -fhalf-no-semantic-interposition -mframe-pointer=none -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/builds/gsasl/shishi/db -resource-dir /usr/lib64/clang/14.0.0 -D HAVE_CONFIG_H -I . -I .. -I ../lib/gl -I ../lib/gl -D LOCALEDIR="/usr/local/share/locale" -D SYSTEMCFGFILE="/usr/local/etc/shishi/shisa.conf" -D DEFAULTDBPATH="/usr/local/var/shishi" -D PIC -internal-isystem /usr/lib64/clang/14.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/12/../../../../x86_64-redhat-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/builds/gsasl/shishi/db -ferror-limit 19 -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /builds/gsasl/shishi/clang-analyzer/2022-08-08-065803-50050-1 -x c fileutil.c
1/* fileutil.c --- Utility functions used by file.c.
2 * Copyright (C) 2002-2022 Simon Josefsson
3 *
4 * This file is part of Shishi.
5 *
6 * Shishi is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Shishi is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with Shishi; if not, see http://www.gnu.org/licenses or write
18 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
19 * Floor, Boston, MA 02110-1301, USA
20 *
21 */
22
23#include "info.h"
24
25/* For stat. */
26#include <sys/stat.h>
27#include <sys/types.h>
28#include <unistd.h>
29
30/* For readdir. */
31#include <dirent.h>
32
33#include <errno(*__errno_location ()).h>
34#ifndef errno(*__errno_location ())
35extern int errno(*__errno_location ());
36#endif
37
38#include "areadlink.h"
39
40/* Get specification. */
41#include "fileutil.h"
42
43#define ishex(c)((c >= '0' || c <= '9') || (c >= 'a' || c <= 'f')
)
((c >= '0' || c <= '9') || (c >= 'a' || c <= 'f'))
44#define tohex(c1,c2)(((c1 - '0' > 9 ? c1 - 'a' + 10 : c1 - '0') << 4) | (
c2 - '0' > 9 ? c2 - 'a' + 10 : c2 - '0'))
(((c1 - '0' > 9 ? c1 - 'a' + 10 : c1 - '0') << 4) | \
45 (c2 - '0' > 9 ? c2 - 'a' + 10 : c2 - '0'))
46
47static char *
48unescape_filename (const char *path)
49{
50 char *out = strdup (path);
51 char *p = out;
52
53 while (*path)
54 {
55 if (path[0] == '%' &&
56 path[1] && ishex (path[1])((path[1] >= '0' || path[1] <= '9') || (path[1] >= 'a'
|| path[1] <= 'f'))
&& path[2] && ishex (path[2])((path[2] >= '0' || path[2] <= '9') || (path[2] >= 'a'
|| path[2] <= 'f'))
)
57 {
58 *p++ = tohex (path[1], path[2])(((path[1] - '0' > 9 ? path[1] - 'a' + 10 : path[1] - '0')
<< 4) | (path[2] - '0' > 9 ? path[2] - 'a' + 10 : path
[2] - '0'))
;
59 path += 3;
60 }
61 else
62 *p++ = *path++;
63 }
64 *p = '\0';
65
66 return out;
67}
68
69static char *
70escape_filename (const char *path)
71{
72 char *out = malloc (strlen (path) * 3 + 1);
73 char *p = out;
74
75 while (*path)
76 {
77 if ((path[0] >= 'a' && path[0] <= 'z') ||
78 (path[0] >= 'A' && path[0] <= 'Z') ||
79 (path[0] >= '0' && path[0] <= '9') ||
80 path[0] == '-' || path[0] == '.')
81 *p++ = *path++;
82 else
83 {
84 int i;
85 *p++ = '%';
86 i = (*path & 0xF0) >> 4;
87 *p++ = i > 10 ? 'a' + i - 10 : '0' + i;
88 i = (*path & 0x0f);
89 *p++ = i > 10 ? 'a' + i - 10 : '0' + i;
90 path++;
91 }
92 }
93 *p = '\0';
94
95 return out;
96}
97
98int
99_shisa_isdir (const char *path)
100{
101 struct stat buf;
102 int rc;
103
104 rc = stat (path, &buf);
105 if (rc != 0 || !S_ISDIR (buf.st_mode)((((buf.st_mode)) & 0170000) == (0040000)))
106 return 0;
107
108 return 1;
109}
110
111static int
112isdir2 (const char *path1, const char *path2)
113{
114 char *tmp;
115 int rc;
116
117 asprintf (&tmp, "%s/%s", path1, path2);
118
119 rc = _shisa_isdir (tmp);
120
121 free (tmp);
122
123 return rc;
124}
125
126
127int
128_shisa_isdir2 (const char *path1, const char *realm)
129{
130 char *saferealm = escape_filename (realm);
131 char *tmp;
132 int rc;
133
134 asprintf (&tmp, "%s/%s", path1, saferealm);
135 free (saferealm);
136
137 rc = _shisa_isdir (tmp);
138
139 free (tmp);
140
141 return rc;
142}
143
144int
145_shisa_isdir3 (const char *path1, const char *realm, const char *principal)
146{
147 char *saferealm = escape_filename (realm);
148 char *safeprincipal = escape_filename (principal);
149 char *tmp;
150 int rc;
151
152 asprintf (&tmp, "%s/%s/%s", path1, saferealm, safeprincipal);
153 free (saferealm);
154 free (safeprincipal);
155
156 rc = _shisa_isdir (tmp);
157
158 free (tmp);
159
160 return rc;
161}
162
163int
164_shisa_isdir4 (const char *path1, const char *realm,
165 const char *principal, const char *path4)
166{
167 char *saferealm = escape_filename (realm);
168 char *safeprincipal = escape_filename (principal);
169 char *tmp;
170 int rc;
171
172 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
173 free (saferealm);
174 free (safeprincipal);
175
176 rc = _shisa_isdir (tmp);
177
178 free (tmp);
179
180 return rc;
181}
182
183int
184_shisa_mkdir (const char *file)
185{
186 int rc;
187
188 rc = mkdir (file, S_IRUSR0400 | S_IWUSR0200 | S_IXUSR0100);
189 if (rc != 0)
190 {
191 perror (file);
192 return -1;
193 }
194
195 return 0;
196}
197
198int
199_shisa_mkdir2 (const char *path1, const char *realm)
200{
201 char *saferealm = escape_filename (realm);
202 char *tmp;
203 int rc;
204
205 asprintf (&tmp, "%s/%s", path1, saferealm);
206 free (saferealm);
207
208 rc = _shisa_mkdir (tmp);
209
210 free (tmp);
211
212 return rc;
213}
214
215int
216_shisa_mkdir3 (const char *path1, const char *realm, const char *principal)
217{
218 char *saferealm = escape_filename (realm);
219 char *safeprincipal = escape_filename (principal);
220 char *tmp;
221 int rc;
222
223 asprintf (&tmp, "%s/%s/%s", path1, saferealm, safeprincipal);
224 free (saferealm);
225 free (safeprincipal);
226
227 rc = _shisa_mkdir (tmp);
228
229 free (tmp);
230
231 return rc;
232}
233
234int
235_shisa_mkdir4 (const char *path1, const char *realm,
236 const char *principal, const char *path4)
237{
238 char *saferealm = escape_filename (realm);
239 char *safeprincipal = escape_filename (principal);
240 char *tmp;
241 int rc;
242
243 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
244 free (saferealm);
245 free (safeprincipal);
246
247 rc = _shisa_mkdir (tmp);
248
249 free (tmp);
250
251 return rc;
252}
253
254int
255_shisa_rmdir (const char *file)
256{
257 int rc;
258
259 rc = rmdir (file);
260 if (rc != 0)
261 {
262 perror (file);
263 return -1;
264 }
265
266 return 0;
267}
268
269int
270_shisa_rmdir2 (const char *path1, const char *realm)
271{
272 char *saferealm = escape_filename (realm);
273 char *tmp;
274 int rc;
275
276 asprintf (&tmp, "%s/%s", path1, saferealm);
277 free (saferealm);
278
279 rc = _shisa_rmdir (tmp);
280
281 free (tmp);
282
283 return rc;
284}
285
286int
287_shisa_rmdir3 (const char *path1, const char *realm, const char *principal)
288{
289 char *saferealm = escape_filename (realm);
290 char *safeprincipal = escape_filename (principal);
291 char *tmp;
292 int rc;
293
294 asprintf (&tmp, "%s/%s/%s", path1, saferealm, safeprincipal);
295 free (saferealm);
296 free (safeprincipal);
297
298 rc = _shisa_rmdir (tmp);
299
300 free (tmp);
301
302 return rc;
303}
304
305int
306_shisa_rmdir4 (const char *path1, const char *realm,
307 const char *principal, const char *path4)
308{
309 char *saferealm = escape_filename (realm);
310 char *safeprincipal = escape_filename (principal);
311 char *tmp;
312 int rc;
313
314 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
315 free (saferealm);
316 free (safeprincipal);
317
318 rc = _shisa_rmdir (tmp);
319
320 free (tmp);
321
322 return rc;
323}
324
325static time_t
326mtime (const char *file)
327{
328 struct stat buf;
329 int rc;
330
331 rc = stat (file, &buf);
332 if (rc != 0 || !S_ISREG (buf.st_mode)((((buf.st_mode)) & 0170000) == (0100000)))
333 return (time_t) - 1;
334
335 return buf.st_atimest_atim.tv_sec;
336}
337
338int
339_shisa_mtime4 (const char *path1,
340 const char *realm, const char *principal, const char *path4)
341{
342 char *saferealm = escape_filename (realm);
343 char *safeprincipal = escape_filename (principal);
344 char *tmp;
345 int rc;
346
347 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
348 free (saferealm);
349 free (safeprincipal);
350
351 rc = mtime (tmp);
352
353 free (tmp);
354
355 return rc;
356}
357
358static int
359isfile (const char *path)
360{
361 struct stat buf;
362 int rc;
363
364 rc = stat (path, &buf);
365 if (rc != 0 || !S_ISREG (buf.st_mode)((((buf.st_mode)) & 0170000) == (0100000)))
366 return 0;
367
368 return 1;
369}
370
371int
372_shisa_isfile4 (const char *path1,
373 const char *realm, const char *principal, const char *path4)
374{
375 char *saferealm = escape_filename (realm);
376 char *safeprincipal = escape_filename (principal);
377 char *tmp;
378 int rc;
379
380 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
381 free (saferealm);
382 free (safeprincipal);
383
384 rc = isfile (tmp);
385
386 free (tmp);
387
388 return rc;
389}
390
391static uint32_t
392uint32link (const char *file)
393{
394 char *linkname;
395 long n;
396
397 linkname = areadlink (file);
398 if (linkname == NULL((void*)0))
399 return 0;
400
401 n = atol (linkname);
402
403 free (linkname);
404
405 return n;
406}
407
408int
409_shisa_uint32link4 (const char *path1,
410 const char *realm,
411 const char *principal, const char *path4)
412{
413 char *saferealm = escape_filename (realm);
414 char *safeprincipal = escape_filename (principal);
415 char *tmp;
416 int rc;
417
418 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
419 free (saferealm);
420 free (safeprincipal);
421
422 rc = uint32link (tmp);
423
424 free (tmp);
425
426 return rc;
427}
428
429static int
430ls_1 (const char *path, int onlydir, char ***files, size_t *nfiles, DIR * dir)
431{
432 struct dirent *de;
433
434 while (errno(*__errno_location ()) = 0, (de = readdir (dir)) != NULL((void*)0))
6
Assuming the condition is false
7
Loop condition is false. Execution continues on line 449
435 {
436 if (strcmp (de->d_name, ".") == 0 || strcmp (de->d_name, "..") == 0)
437 continue;
438 if (!onlydir || isdir2 (path, de->d_name))
439 {
440 if (files)
441 {
442 *files = xrealloc (*files, (*nfiles + 1) * sizeof (**files));
443 (*files)[(*nfiles)] = unescape_filename (de->d_name);
444 }
445 (*nfiles)++;
446 }
447 }
448
449 if (errno(*__errno_location ()) != 0)
8
Assuming the condition is true
9
Taking true branch
450 {
451 size_t i;
452
453 perror (path);
454
455 if (files)
10
Assuming 'files' is non-null
11
Taking true branch
456 {
457 for (i = 0; i < *nfiles; i++)
12
Assuming the condition is true
13
Loop condition is true. Entering loop body
15
Assuming the condition is true
16
Loop condition is true. Entering loop body
458 free (**files);
14
Memory is released
17
Attempt to free released memory
459 if (*nfiles > 0)
460 free (*files);
461 }
462
463 return -1;
464 }
465
466 return 0;
467}
468
469static int
470ls (const char *path, int onlydir, char ***files, size_t *nfiles)
471{
472 DIR *dir;
473 int rc;
474
475 dir = opendir (path);
476 if (dir == NULL((void*)0))
3
Assuming 'dir' is not equal to NULL
4
Taking false branch
477 {
478 perror (path);
479 return -1;
480 }
481
482 if (ls_1 (path, onlydir, files, nfiles, dir) != 0)
5
Calling 'ls_1'
483 {
484 rc = closedir (dir);
485 if (rc != 0)
486 perror (path);
487 return -1;
488 }
489
490 rc = closedir (dir);
491 if (rc != 0)
492 {
493 size_t i;
494
495 perror (path);
496
497 if (files)
498 {
499 for (i = 0; i < *nfiles; i++)
500 free (**files);
501 if (*nfiles > 0)
502 free (*files);
503 }
504
505 return -1;
506 }
507
508 return 0;
509}
510
511int
512_shisa_ls (const char *path, char ***files, size_t *nfiles)
513{
514 return ls (path, 0, files, nfiles);
515}
516
517int
518_shisa_ls2 (const char *path, const char *realm,
519 char ***files, size_t *nfiles)
520{
521 char *saferealm = escape_filename (realm);
522 char *tmp;
523 int rc;
524
525 asprintf (&tmp, "%s/%s", path, saferealm);
526 free (saferealm);
527
528 rc = _shisa_ls (tmp, files, nfiles);
529
530 free (tmp);
531
532 return rc;
533}
534
535int
536_shisa_ls3 (const char *path, const char *realm,
537 const char *principal, char ***files, size_t *nfiles)
538{
539 char *saferealm = escape_filename (realm);
540 char *safeprincipal = escape_filename (principal);
541 char *tmp;
542 int rc;
543
544 asprintf (&tmp, "%s/%s/%s", path, saferealm, safeprincipal);
545 free (saferealm);
546 free (safeprincipal);
547
548 rc = _shisa_ls (tmp, files, nfiles);
549
550 free (tmp);
551
552 return rc;
553}
554
555int
556_shisa_ls4 (const char *path, const char *realm,
557 const char *principal, const char *path4,
558 char ***files, size_t *nfiles)
559{
560 char *saferealm = escape_filename (realm);
561 char *safeprincipal = escape_filename (principal);
562 char *tmp;
563 int rc;
564
565 asprintf (&tmp, "%s/%s/%s/%s", path, saferealm, safeprincipal, path4);
566 free (saferealm);
567 free (safeprincipal);
568
569 rc = _shisa_ls (tmp, files, nfiles);
570
571 free (tmp);
572
573 return rc;
574}
575
576int
577_shisa_lsdir (const char *path, char ***files, size_t *nfiles)
578{
579 return ls (path, 1, files, nfiles);
2
Calling 'ls'
580}
581
582int
583_shisa_lsdir2 (const char *path, const char *realm,
584 char ***files, size_t *nfiles)
585{
586 char *saferealm = escape_filename (realm);
587 char *tmp;
588 int rc;
589
590 asprintf (&tmp, "%s/%s", path, saferealm);
591 free (saferealm);
592
593 rc = _shisa_lsdir (tmp, files, nfiles);
1
Calling '_shisa_lsdir'
594
595 free (tmp);
596
597 return rc;
598}
599
600static int
601rm (const char *path)
602{
603 int rc;
604
605 rc = unlink (path);
606 if (rc != 0)
607 {
608 perror (path);
609 return -1;
610 }
611
612 return 0;
613}
614
615int
616_shisa_rm4 (const char *path1, const char *realm,
617 const char *principal, const char *path4)
618{
619 char *saferealm = escape_filename (realm);
620 char *safeprincipal = escape_filename (principal);
621 char *tmp;
622 int rc;
623
624 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
625 free (saferealm);
626 free (safeprincipal);
627
628 rc = rm (tmp);
629
630 free (tmp);
631
632 return rc;
633}
634
635int
636_shisa_rm5 (const char *path1, const char *realm, const char *principal,
637 const char *path4, const char *path5)
638{
639 char *saferealm = escape_filename (realm);
640 char *safeprincipal = escape_filename (principal);
641 char *tmp;
642 int rc;
643
644 asprintf (&tmp, "%s/%s/%s/%s/%s", path1, saferealm, safeprincipal,
645 path4, path5);
646 free (saferealm);
647 free (safeprincipal);
648
649 rc = rm (tmp);
650
651 free (tmp);
652
653 return rc;
654}
655
656FILE *
657_shisa_fopen4 (const char *path1, const char *realm,
658 const char *principal, const char *path4, const char *mode)
659{
660 char *saferealm = escape_filename (realm);
661 char *safeprincipal = escape_filename (principal);
662 char *tmp;
663 FILE *fh;
664
665 asprintf (&tmp, "%s/%s/%s/%s", path1, saferealm, safeprincipal, path4);
666 free (saferealm);
667 free (safeprincipal);
668
669 fh = fopen (tmp, mode);
670
671 free (tmp);
672
673 return fh;
674}