Bug Summary

File:src/lib/libc/stdio/getdelim.c
Warning:line 113, column 9
Null pointer passed as 1st argument to memory copy function

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 getdelim.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/lib/libc/obj -resource-dir /usr/local/lib/clang/13.0.0 -include namespace.h -I /usr/src/lib/libc/include -I /usr/src/lib/libc/hidden -D __LIBC__ -D APIWARN -D YP -I /usr/src/lib/libc/yp -I /usr/src/lib/libc -I /usr/src/lib/libc/gdtoa -I /usr/src/lib/libc/arch/amd64/gdtoa -D INFNAN_CHECK -D MULTIPLE_THREADS -D NO_FENV_H -D USE_LOCALE -I /usr/src/lib/libc -I /usr/src/lib/libc/citrus -D RESOLVSORT -D FLOATING_POINT -D PRINTF_WIDE_CHAR -D SCANF_WIDE_CHAR -D FUTEX -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/lib/libc/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/lib/libc/stdio/getdelim.c
1/* $OpenBSD: getdelim.c,v 1.6 2017/04/13 18:36:51 brynet Exp $ */
2/* $NetBSD: getdelim.c,v 1.13 2011/07/22 23:12:30 joerg Exp $ */
3
4/*
5 * Copyright (c) 2009 The NetBSD Foundation, Inc.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Roy Marples.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <errno(*__errno()).h>
32#include <limits.h>
33#include <stdint.h>
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include "local.h"
39
40/* Minimum buffer size we create.
41 * This should allow config files to fit into our power of 2 buffer growth
42 * without the need for a realloc. */
43#define MINBUF128 128
44
45ssize_t
46getdelim(char **__restrict buf, size_t *__restrict buflen,
47 int sep, FILE *__restrict fp)
48{
49 unsigned char *p;
50 size_t len, newlen, off;
51 char *newb;
52
53 FLOCKFILE(fp)do { if (_thread_cb.tc_flockfile != ((void *)0)) _thread_cb.tc_flockfile
(fp); } while (0)
;
1
Assuming field 'tc_flockfile' is equal to null
2
Taking false branch
3
Loop condition is false. Exiting loop
54
55 if (buf == NULL((void *)0) || buflen == NULL((void *)0)) {
4
Assuming 'buf' is not equal to NULL
5
Assuming 'buflen' is not equal to NULL
6
Taking false branch
56 errno(*__errno()) = EINVAL22;
57 goto error;
58 }
59
60 /* If buf is NULL, we have to assume a size of zero */
61 if (*buf == NULL((void *)0))
7
Assuming pointer value is null
8
Taking true branch
62 *buflen = 0;
63
64 _SET_ORIENTATION(fp, -1)do { struct wchar_io_data *_wcio = (((struct __sfileext *)((fp
)->_ext._base)) ? &(((struct __sfileext *)((fp)->_ext
._base))->_wcio) : (struct wchar_io_data *)0); if (_wcio &&
_wcio->wcio_mode == 0) _wcio->wcio_mode = (-1);} while
(0)
;
9
Assuming field '_base' is null
10
'?' condition is false
11
Loop condition is false. Exiting loop
65 off = 0;
66 do {
67 /* If the input buffer is empty, refill it */
68 if (fp->_r <= 0 && __srefill(fp)) {
12
Assuming field '_r' is > 0
69 if (__sferror(fp)(((fp)->_flags & 0x0040) != 0))
70 goto error;
71 /* No error, so EOF. */
72 break;
73 }
74
75 /* Scan through looking for the separator */
76 p = memchr(fp->_p, sep, fp->_r);
77 if (p == NULL((void *)0))
13
Assuming 'p' is not equal to NULL
14
Taking false branch
78 len = fp->_r;
79 else
80 len = (p - fp->_p) + 1;
81
82 /* Ensure we can handle it */
83 if (off
14.1
'off' is <= SSIZE_MAX
> SSIZE_MAX9223372036854775807L || len + 1 > SSIZE_MAX9223372036854775807L - off) {
15
Assuming the condition is false
16
Taking false branch
84 errno(*__errno()) = EOVERFLOW87;
85 goto error;
86 }
87 newlen = off + len + 1; /* reserve space for NUL terminator */
88 if (newlen > *buflen) {
17
Assuming the condition is false
18
Taking false branch
89 if (newlen < MINBUF128)
90 newlen = MINBUF128;
91#define powerof2(x)((((x)-1)&(x))==0) ((((x)-1)&(x))==0)
92 if (!powerof2(newlen)((((newlen)-1)&(newlen))==0)) {
93 /* Grow the buffer to the next power of 2 */
94 newlen--;
95 newlen |= newlen >> 1;
96 newlen |= newlen >> 2;
97 newlen |= newlen >> 4;
98 newlen |= newlen >> 8;
99 newlen |= newlen >> 16;
100#if SIZE_MAX0xffffffffffffffffUL > 0xffffffffU
101 newlen |= newlen >> 32;
102#endif
103 newlen++;
104 }
105
106 newb = recallocarray(*buf, *buflen, newlen, 1);
107 if (newb == NULL((void *)0))
108 goto error;
109 *buf = newb;
110 *buflen = newlen;
111 }
112
113 (void)memcpy((*buf + off), fp->_p, len);
19
Null pointer passed as 1st argument to memory copy function
114 /* Safe, len is never greater than what fp->_r can fit. */
115 fp->_r -= (int)len;
116 fp->_p += (int)len;
117 off += len;
118 } while (p == NULL((void *)0));
119
120 FUNLOCKFILE(fp)do { if (_thread_cb.tc_funlockfile != ((void *)0)) _thread_cb
.tc_funlockfile(fp); } while (0)
;
121
122 /* POSIX demands we return -1 on EOF. */
123 if (off == 0)
124 return -1;
125
126 if (*buf != NULL((void *)0))
127 *(*buf + off) = '\0';
128 return off;
129
130error:
131 fp->_flags |= __SERR0x0040;
132 FUNLOCKFILE(fp)do { if (_thread_cb.tc_funlockfile != ((void *)0)) _thread_cb
.tc_funlockfile(fp); } while (0)
;
133 return -1;
134}
135DEF_WEAK(getdelim)__asm__(".weak " "getdelim" " ; " "getdelim" " = " "_libc_getdelim"
)
;