Bug Summary

File:src/usr.sbin/iscsid/iscsid.c
Warning:line 100, column 2
Value stored to 'argv' is never read

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 iscsid.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.sbin/iscsid/obj -resource-dir /usr/local/lib/clang/13.0.0 -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/iscsid/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.sbin/iscsid/iscsid.c
1/* $OpenBSD: iscsid.c,v 1.22 2021/04/16 14:37:06 claudio Exp $ */
2
3/*
4 * Copyright (c) 2009 Claudio Jeker <claudio@openbsd.org>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <sys/queue.h>
20#include <sys/socket.h>
21#include <sys/sysctl.h>
22#include <sys/time.h>
23#include <sys/uio.h>
24
25#include <err.h>
26#include <event.h>
27#include <pwd.h>
28#include <signal.h>
29#include <stdio.h>
30#include <stdlib.h>
31#include <string.h>
32#include <unistd.h>
33
34#include "iscsid.h"
35#include "log.h"
36
37void main_sig_handler(int, short, void *);
38__dead__attribute__((__noreturn__)) void usage(void);
39void shutdown_cb(int, short, void *);
40
41extern struct initiator *initiator;
42struct event exit_ev;
43int exit_rounds;
44#define ISCSI_EXIT_WAIT5 5
45
46const struct session_params iscsi_sess_defaults = {
47 .MaxBurstLength = 262144,
48 .FirstBurstLength = 65536,
49 .DefaultTime2Wait = 2,
50 .DefaultTime2Retain = 20,
51 .MaxOutstandingR2T = 1,
52 .MaxConnections = 1,
53 .InitialR2T = 1,
54 .ImmediateData = 1,
55 .DataPDUInOrder = 1,
56 .DataSequenceInOrder = 1,
57 .ErrorRecoveryLevel = 0
58};
59
60const struct connection_params iscsi_conn_defaults = {
61 .MaxRecvDataSegmentLength = 8192
62};
63
64int
65main(int argc, char *argv[])
66{
67 struct event ev_sigint, ev_sigterm, ev_sighup;
68 struct passwd *pw;
69 char *ctrlsock = ISCSID_CONTROL"/var/run/iscsid.sock";
70 char *vscsidev = ISCSID_DEVICE"/dev/vscsi0";
71 int name[] = { CTL_KERN1, KERN_PROC_NOBROADCASTKILL79, 0 };
72 int ch, debug = 0, verbose = 0, nobkill = 1;
73
74 log_procname = getprogname();
75
76 log_init(1); /* log to stderr until daemonized */
77 log_verbose(1);
78
79 while ((ch = getopt(argc, argv, "dn:s:v")) != -1) {
80 switch (ch) {
81 case 'd':
82 debug = 1;
83 break;
84 case 'n':
85 vscsidev = optarg;
86 break;
87 case 's':
88 ctrlsock = optarg;
89 break;
90 case 'v':
91 verbose = 1;
92 break;
93 default:
94 usage();
95 /* NOTREACHED */
96 }
97 }
98
99 argc -= optind;
100 argv += optind;
Value stored to 'argv' is never read
101
102 if (argc > 0)
103 usage();
104
105 /* check for root privileges */
106 if (geteuid())
107 errx(1, "need root privileges");
108
109 log_init(debug);
110 log_verbose(verbose);
111
112 if (control_init(ctrlsock) == -1)
113 fatalx("control socket setup failed");
114
115 if (!debug)
116 daemon(1, 0);
117 log_info("startup");
118
119 name[2] = getpid();
120 if (sysctl(name, 3, NULL((void *)0), 0, &nobkill, sizeof(nobkill)) != 0)
121 fatal("sysctl");
122
123 event_init();
124 vscsi_open(vscsidev);
125
126 /* chroot and drop to iscsid user */
127 if ((pw = getpwnam(ISCSID_USER"_iscsid")) == NULL((void *)0))
128 errx(1, "unknown user %s", ISCSID_USER"_iscsid");
129
130 if (chroot(pw->pw_dir) == -1)
131 fatal("chroot");
132 if (chdir("/") == -1)
133 fatal("chdir(\"/\")");
134 if (setgroups(1, &pw->pw_gid) ||
135 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
136 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
137 fatal("can't drop privileges");
138
139 /* setup signal handler */
140 signal_set(&ev_sigint, SIGINT, main_sig_handler, NULL)event_set(&ev_sigint, 2, 0x08|0x10, main_sig_handler, ((void
*)0))
;
141 signal_set(&ev_sigterm, SIGTERM, main_sig_handler, NULL)event_set(&ev_sigterm, 15, 0x08|0x10, main_sig_handler, (
(void *)0))
;
142 signal_set(&ev_sighup, SIGHUP, main_sig_handler, NULL)event_set(&ev_sighup, 1, 0x08|0x10, main_sig_handler, ((void
*)0))
;
143 signal_add(&ev_sigint, NULL)event_add(&ev_sigint, ((void *)0));
144 signal_add(&ev_sigterm, NULL)event_add(&ev_sigterm, ((void *)0));
145 signal_add(&ev_sighup, NULL)event_add(&ev_sighup, ((void *)0));
146 signal(SIGPIPE13, SIG_IGN(void (*)(int))1);
147
148 control_event_init();
149 initiator = initiator_init();
150
151 event_dispatch();
152
153 /* do some cleanup on the way out */
154 control_cleanup(ctrlsock);
155 initiator_cleanup(initiator);
156 log_info("exiting.");
157 return 0;
158}
159
160void
161shutdown_cb(int fd, short event, void *arg)
162{
163 struct timeval tv;
164
165 if (exit_rounds++ >= ISCSI_EXIT_WAIT5 || initiator_isdown(initiator))
166 event_loopexit(NULL((void *)0));
167
168 timerclear(&tv)(&tv)->tv_sec = (&tv)->tv_usec = 0;
169 tv.tv_sec = 1;
170
171 if (evtimer_add(&exit_ev, &tv)event_add(&exit_ev, &tv) == -1)
172 fatal("shutdown_cb");
173}
174
175void
176main_sig_handler(int sig, short event, void *arg)
177{
178 struct timeval tv;
179
180 /* signal handler rules don't apply, libevent decouples for us */
181 switch (sig) {
182 case SIGTERM15:
183 case SIGINT2:
184 case SIGHUP1:
185 initiator_shutdown(initiator);
186 evtimer_set(&exit_ev, shutdown_cb, NULL)event_set(&exit_ev, -1, 0, shutdown_cb, ((void *)0));
187 timerclear(&tv)(&tv)->tv_sec = (&tv)->tv_usec = 0;
188 if (evtimer_add(&exit_ev, &tv)event_add(&exit_ev, &tv) == -1)
189 fatal("main_sig_handler");
190 break;
191 default:
192 fatalx("unexpected signal");
193 /* NOTREACHED */
194 }
195}
196
197__dead__attribute__((__noreturn__)) void
198usage(void)
199{
200 extern char *__progname;
201
202 fprintf(stderr(&__sF[2]), "usage: %s [-dv] [-n device] [-s socket]\n",
203 __progname);
204 exit(1);
205}
206
207void
208iscsid_ctrl_dispatch(void *ch, struct pdu *pdu)
209{
210 struct ctrlmsghdr *cmh;
211 struct initiator_config *ic;
212 struct session_config *sc;
213 struct session *s;
214 struct session_poll p = { 0 };
215 int *valp;
216
217 cmh = pdu_getbuf(pdu, NULL((void *)0), 0);
218 if (cmh == NULL((void *)0))
219 goto done;
220
221 switch (cmh->type) {
222 case CTRL_INITIATOR_CONFIG4:
223 if (cmh->len[0] != sizeof(*ic)) {
224 log_warnx("CTRL_INITIATOR_CONFIG bad size");
225 control_compose(ch, CTRL_FAILURE2, NULL((void *)0), 0);
226 break;
227 }
228 ic = pdu_getbuf(pdu, NULL((void *)0), 1);
229 memcpy(&initiator->config, ic, sizeof(initiator->config));
230 control_compose(ch, CTRL_SUCCESS1, NULL((void *)0), 0);
231 break;
232 case CTRL_SESSION_CONFIG5:
233 if (cmh->len[0] != sizeof(*sc)) {
234 log_warnx("CTRL_SESSION_CONFIG bad size");
235 control_compose(ch, CTRL_FAILURE2, NULL((void *)0), 0);
236 break;
237 }
238 sc = pdu_getbuf(pdu, NULL((void *)0), 1);
239 if (cmh->len[1])
240 sc->TargetName = pdu_getbuf(pdu, NULL((void *)0), 2);
241 else if (sc->SessionType != SESSION_TYPE_DISCOVERY1) {
242 control_compose(ch, CTRL_FAILURE2, NULL((void *)0), 0);
243 goto done;
244 } else
245 sc->TargetName = NULL((void *)0);
246 if (cmh->len[2])
247 sc->InitiatorName = pdu_getbuf(pdu, NULL((void *)0), 3);
248 else
249 sc->InitiatorName = NULL((void *)0);
250
251 s = session_find(initiator, sc->SessionName);
252 if (s == NULL((void *)0)) {
253 s = session_new(initiator, sc->SessionType);
254 if (s == NULL((void *)0)) {
255 control_compose(ch, CTRL_FAILURE2, NULL((void *)0), 0);
256 goto done;
257 }
258 }
259
260 session_config(s, sc);
261 if (s->state == SESS_INIT0x0001)
262 session_fsm(s, SESS_EV_START, NULL((void *)0), 0);
263
264 control_compose(ch, CTRL_SUCCESS1, NULL((void *)0), 0);
265 break;
266 case CTRL_LOG_VERBOSE6:
267 if (cmh->len[0] != sizeof(int)) {
268 log_warnx("CTRL_LOG_VERBOSE bad size");
269 control_compose(ch, CTRL_FAILURE2, NULL((void *)0), 0);
270 break;
271 }
272 valp = pdu_getbuf(pdu, NULL((void *)0), 1);
273 log_verbose(*valp);
274 control_compose(ch, CTRL_SUCCESS1, NULL((void *)0), 0);
275 break;
276 case CTRL_VSCSI_STATS7:
277 control_compose(ch, CTRL_VSCSI_STATS7, vscsi_stats(),
278 sizeof(struct vscsi_stats));
279 break;
280 case CTRL_SHOW_SUM8:
281 control_compose(ch, CTRL_INITIATOR_CONFIG4, &initiator->config,
282 sizeof(initiator->config));
283
284 TAILQ_FOREACH(s, &initiator->sessions, entry)for((s) = ((&initiator->sessions)->tqh_first); (s) !=
((void *)0); (s) = ((s)->entry.tqe_next))
{
285 struct ctrldata cdv[3];
286 bzero(cdv, sizeof(cdv));
287
288 cdv[0].buf = &s->config;
289 cdv[0].len = sizeof(s->config);
290
291 if (s->config.TargetName) {
292 cdv[1].buf = s->config.TargetName;
293 cdv[1].len =
294 strlen(s->config.TargetName) + 1;
295 }
296 if (s->config.InitiatorName) {
297 cdv[2].buf = s->config.InitiatorName;
298 cdv[2].len =
299 strlen(s->config.InitiatorName) + 1;
300 }
301
302 control_build(ch, CTRL_SESSION_CONFIG5,
303 nitems(cdv)(sizeof((cdv)) / sizeof((cdv)[0])), cdv);
304 }
305
306 control_compose(ch, CTRL_SUCCESS1, NULL((void *)0), 0);
307 break;
308 case CTRL_SESS_POLL9:
309 TAILQ_FOREACH(s, &initiator->sessions, entry)for((s) = ((&initiator->sessions)->tqh_first); (s) !=
((void *)0); (s) = ((s)->entry.tqe_next))
310 poll_session(&p, s);
311 poll_finalize(&p);
312 control_compose(ch, CTRL_SESS_POLL9, &p, sizeof(p));
313 break;
314 default:
315 log_warnx("unknown control message type %d", cmh->type);
316 control_compose(ch, CTRL_FAILURE2, NULL((void *)0), 0);
317 break;
318 }
319
320done:
321 pdu_free(pdu);
322}
323
324#define MERGE_MIN(r, a, b, v) \
325 r->v = (a->v < b->v ? a->v : b->v)
326#define MERGE_MAX(r, a, b, v) \
327 r->v = (a->v > b->v ? a->v : b->v)
328#define MERGE_OR(r, a, b, v) \
329 r->v = (a->v || b->v)
330#define MERGE_AND(r, a, b, v) \
331 r->v = (a->v && b->v)
332
333void
334iscsi_merge_sess_params(struct session_params *res,
335 struct session_params *mine, struct session_params *his)
336{
337 MERGE_MIN(res, mine, his, MaxBurstLength);
338 MERGE_MIN(res, mine, his, FirstBurstLength);
339 MERGE_MAX(res, mine, his, DefaultTime2Wait);
340 MERGE_MIN(res, mine, his, DefaultTime2Retain);
341 MERGE_MIN(res, mine, his, MaxOutstandingR2T);
342 res->TargetPortalGroupTag = his->TargetPortalGroupTag;
343 MERGE_MIN(res, mine, his, MaxConnections);
344 MERGE_OR(res, mine, his, InitialR2T);
345 MERGE_AND(res, mine, his, ImmediateData);
346 MERGE_OR(res, mine, his, DataPDUInOrder);
347 MERGE_OR(res, mine, his, DataSequenceInOrder);
348 MERGE_MIN(res, mine, his, ErrorRecoveryLevel);
349
350}
351
352void
353iscsi_merge_conn_params(struct connection_params *res,
354 struct connection_params *mine, struct connection_params *his)
355{
356 res->MaxRecvDataSegmentLength = his->MaxRecvDataSegmentLength;
357 /* XXX HeaderDigest and DataDigest */
358}
359
360#undef MERGE_MIN
361#undef MERGE_MAX
362#undef MERGE_OR
363#undef MERGE_AND