Bug Summary

File:src/lib/libc/asr/getnameinfo_async.c
Warning:line 157, column 8
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'

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 getnameinfo_async.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 -fhalf-no-semantic-interposition -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 -D PIC -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/asr/getnameinfo_async.c
1/* $OpenBSD: getnameinfo_async.c,v 1.15 2020/12/21 09:40:35 eric Exp $ */
2/*
3 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#include <sys/types.h>
19#include <sys/socket.h>
20#include <net/if.h>
21#include <netinet/in.h>
22#include <arpa/inet.h>
23#include <arpa/nameser.h>
24#include <netdb.h>
25
26#include <asr.h>
27#include <errno(*__errno()).h>
28#include <stdlib.h>
29#include <string.h>
30#include <unistd.h>
31
32#include "asr_private.h"
33
34static int getnameinfo_async_run(struct asr_query *, struct asr_result *);
35static int _servname(struct asr_query *);
36static int _numerichost(struct asr_query *);
37
38struct asr_query *
39getnameinfo_async(const struct sockaddr *sa, socklen_t slen, char *host,
40 size_t hostlen, char *serv, size_t servlen, int flags, void *asr)
41{
42 struct asr_ctx *ac;
43 struct asr_query *as;
44
45 ac = _asr_use_resolver(asr);
46 if ((as = _asr_async_new(ac, ASR_GETNAMEINFO)) == NULL((void *)0))
47 goto abort; /* errno set */
48 as->as_run = getnameinfo_async_run;
49
50 if (sa->sa_family == AF_INET2)
51 memmove(&as->as.ni.sa.sa, sa, sizeof (as->as.ni.sa.sain));
52 else if (sa->sa_family == AF_INET624)
53 memmove(&as->as.ni.sa.sa, sa, sizeof (as->as.ni.sa.sain6));
54
55 as->as.ni.sa.sa.sa_len = slen;
56 as->as.ni.hostname = host;
57 as->as.ni.hostnamelen = hostlen;
58 as->as.ni.servname = serv;
59 as->as.ni.servnamelen = servlen;
60 as->as.ni.flags = flags;
61
62 _asr_ctx_unref(ac);
63 return (as);
64
65 abort:
66 if (as)
67 _asr_async_free(as);
68 _asr_ctx_unref(ac);
69 return (NULL((void *)0));
70}
71DEF_WEAK(getnameinfo_async)__asm__(".weak " "getnameinfo_async" " ; " "getnameinfo_async"
" = " "_libc_getnameinfo_async")
;
72
73static int
74getnameinfo_async_run(struct asr_query *as, struct asr_result *ar)
75{
76 void *addr;
77 socklen_t addrlen;
78 int r;
79
80 next:
81 switch (as->as_state) {
82
83 case ASR_STATE_INIT:
84
85 /* Make sure the parameters are all valid. */
86
87 if (as->as.ni.sa.sa.sa_family != AF_INET2 &&
88 as->as.ni.sa.sa.sa_family != AF_INET624) {
89 ar->ar_gai_errno = EAI_FAMILY-6;
90 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
91 break;
92 }
93
94 if ((as->as.ni.sa.sa.sa_family == AF_INET2 &&
95 (as->as.ni.sa.sa.sa_len != sizeof (as->as.ni.sa.sain))) ||
96 (as->as.ni.sa.sa.sa_family == AF_INET624 &&
97 (as->as.ni.sa.sa.sa_len != sizeof (as->as.ni.sa.sain6)))) {
98 ar->ar_gai_errno = EAI_FAIL-4;
99 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
100 break;
101 }
102
103 /* Set the service name first, if needed. */
104 if (_servname(as) == -1) {
105 ar->ar_gai_errno = EAI_OVERFLOW-14;
106 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
107 break;
108 }
109
110 if (as->as.ni.hostname == NULL((void *)0) || as->as.ni.hostnamelen == 0) {
111 ar->ar_gai_errno = 0;
112 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
113 break;
114 }
115
116 if (as->as.ni.flags & NI_NUMERICHOST1) {
117 if (_numerichost(as) == -1) {
118 if (errno(*__errno()) == ENOMEM12)
119 ar->ar_gai_errno = EAI_MEMORY-10;
120 else if (errno(*__errno()) == ENOSPC28)
121 ar->ar_gai_errno = EAI_OVERFLOW-14;
122 else {
123 ar->ar_errno = errno(*__errno());
124 ar->ar_gai_errno = EAI_SYSTEM-11;
125 }
126 } else
127 ar->ar_gai_errno = 0;
128 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
129 break;
130 }
131
132 if (as->as.ni.sa.sa.sa_family == AF_INET2) {
133 addrlen = sizeof(as->as.ni.sa.sain.sin_addr);
134 addr = &as->as.ni.sa.sain.sin_addr;
135 } else {
136 addrlen = sizeof(as->as.ni.sa.sain6.sin6_addr);
137 addr = &as->as.ni.sa.sain6.sin6_addr;
138 }
139
140 /*
141 * Create a subquery to lookup the address.
142 */
143 as->as_subq = _gethostbyaddr_async_ctx(addr, addrlen,
144 as->as.ni.sa.sa.sa_family,
145 as->as_ctx);
146 if (as->as_subq == NULL((void *)0)) {
147 ar->ar_gai_errno = EAI_MEMORY-10;
148 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
149 break;
150 }
151
152 async_set_state(as, ASR_STATE_SUBQUERY)do { ; (as)->as_state = (ASR_STATE_SUBQUERY); } while (0);
153 break;
154
155 case ASR_STATE_SUBQUERY:
156
157 if ((r = asr_run(as->as_subq, ar)) == ASYNC_COND0)
Although the value stored to 'r' is used in the enclosing expression, the value is never actually read from 'r'
158 return (ASYNC_COND0);
159
160 /*
161 * Request done.
162 */
163 as->as_subq = NULL((void *)0);
164
165 if (ar->ar_hostent == NULL((void *)0)) {
166 if (as->as.ni.flags & NI_NAMEREQD8) {
167 ar->ar_gai_errno = EAI_NONAME-2;
168 } else if (_numerichost(as) == -1) {
169 if (errno(*__errno()) == ENOMEM12)
170 ar->ar_gai_errno = EAI_MEMORY-10;
171 else if (errno(*__errno()) == ENOSPC28)
172 ar->ar_gai_errno = EAI_OVERFLOW-14;
173 else {
174 ar->ar_errno = errno(*__errno());
175 ar->ar_gai_errno = EAI_SYSTEM-11;
176 }
177 } else
178 ar->ar_gai_errno = 0;
179 } else {
180 if (strlcpy(as->as.ni.hostname,
181 ar->ar_hostent->h_name,
182 as->as.ni.hostnamelen) >= as->as.ni.hostnamelen)
183 ar->ar_gai_errno = EAI_OVERFLOW-14;
184 else
185 ar->ar_gai_errno = 0;
186 free(ar->ar_hostent);
187 }
188
189 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
190 break;
191
192 case ASR_STATE_HALT:
193 return (ASYNC_DONE1);
194
195 default:
196 ar->ar_errno = EOPNOTSUPP45;
197 ar->ar_gai_errno = EAI_SYSTEM-11;
198 async_set_state(as, ASR_STATE_HALT)do { ; (as)->as_state = (ASR_STATE_HALT); } while (0);
199 break;
200 }
201 goto next;
202}
203
204
205/*
206 * Set the service name on the result buffer is not NULL.
207 * return (-1) if the buffer is too small.
208 */
209static int
210_servname(struct asr_query *as)
211{
212 struct servent s;
213 struct servent_data sd;
214 int port, r;
215 char *buf = as->as.ni.servname;
216 size_t n, buflen = as->as.ni.servnamelen;
217
218 if (as->as.ni.servname == NULL((void *)0) || as->as.ni.servnamelen == 0)
219 return (0);
220
221 if (as->as.ni.sa.sa.sa_family == AF_INET2)
222 port = as->as.ni.sa.sain.sin_port;
223 else
224 port = as->as.ni.sa.sain6.sin6_port;
225
226 if (!(as->as.ni.flags & NI_NUMERICSERV2)) {
227 memset(&sd, 0, sizeof (sd));
228 r = getservbyport_r(port, (as->as.ni.flags & NI_DGRAM16) ?
229 "udp" : "tcp", &s, &sd);
230 if (r == 0)
231 n = strlcpy(buf, s.s_name, buflen);
232 endservent_r(&sd);
233 if (r == 0) {
234 if (n >= buflen)
235 return (-1);
236 return (0);
237 }
238 }
239
240 r = snprintf(buf, buflen, "%u", ntohs(port)(__uint16_t)(__builtin_constant_p(port) ? (__uint16_t)(((__uint16_t
)(port) & 0xffU) << 8 | ((__uint16_t)(port) & 0xff00U
) >> 8) : __swap16md(port))
);
241 if (r < 0 || r >= buflen)
242 return (-1);
243
244 return (0);
245}
246
247/*
248 * Write the numeric address
249 */
250static int
251_numerichost(struct asr_query *as)
252{
253 unsigned int ifidx;
254 char scope[IF_NAMESIZE16 + 1], *ifname;
255 void *addr;
256 char *buf = as->as.ni.hostname;
257 size_t buflen = as->as.ni.hostnamelen;
258
259 if (as->as.ni.sa.sa.sa_family == AF_INET2)
260 addr = &as->as.ni.sa.sain.sin_addr;
261 else
262 addr = &as->as.ni.sa.sain6.sin6_addr;
263
264 if (inet_ntop(as->as.ni.sa.sa.sa_family, addr, buf, buflen) == NULL((void *)0))
265 return (-1); /* errno set */
266
267 if (as->as.ni.sa.sa.sa_family == AF_INET624 &&
268 as->as.ni.sa.sain6.sin6_scope_id) {
269
270 scope[0] = SCOPE_DELIMITER'%';
271 scope[1] = '\0';
272
273 ifidx = as->as.ni.sa.sain6.sin6_scope_id;
274 ifname = NULL((void *)0);
275
276 if (IN6_IS_ADDR_LINKLOCAL(&as->as.ni.sa.sain6.sin6_addr)(((&as->as.ni.sa.sain6.sin6_addr)->__u6_addr.__u6_addr8
[0] == 0xfe) && (((&as->as.ni.sa.sain6.sin6_addr
)->__u6_addr.__u6_addr8[1] & 0xc0) == 0x80))
||
277 IN6_IS_ADDR_MC_LINKLOCAL(&as->as.ni.sa.sain6.sin6_addr)(((&as->as.ni.sa.sain6.sin6_addr)->__u6_addr.__u6_addr8
[0] == 0xff) && (((&as->as.ni.sa.sain6.sin6_addr
)->__u6_addr.__u6_addr8[1] & 0x0f) == 0x02))
||
278 IN6_IS_ADDR_MC_INTFACELOCAL(&as->as.ni.sa.sain6.sin6_addr)(((&as->as.ni.sa.sain6.sin6_addr)->__u6_addr.__u6_addr8
[0] == 0xff) && (((&as->as.ni.sa.sain6.sin6_addr
)->__u6_addr.__u6_addr8[1] & 0x0f) == 0x01))
)
279 ifname = if_indextoname(ifidx, scope + 1);
280
281 if (ifname == NULL((void *)0))
282 snprintf(scope + 1, sizeof(scope) - 1, "%u", ifidx);
283
284 strlcat(buf, scope, buflen);
285 }
286
287 return (0);
288}