Bug Summary

File:src/usr.sbin/apm/apm.c
Warning:line 122, column 6
Branch condition evaluates to a garbage value

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 apm.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/apm/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/usr.sbin/apm/../apmd -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/usr.sbin/apm/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/apm/apm.c
1/* $OpenBSD: apm.c,v 1.38 2021/04/06 20:30:32 kn Exp $ */
2
3/*
4 * Copyright (c) 1996 John T. Kohl
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
22 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
27 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 *
30 */
31
32#include <sys/types.h>
33#include <sys/sysctl.h>
34#include <sys/socket.h>
35#include <sys/un.h>
36#include <sys/ioctl.h>
37#include <machine/apmvar.h>
38#include <stdio.h>
39#include <stdlib.h>
40#include <unistd.h>
41#include <fcntl.h>
42#include <errno(*__errno()).h>
43#include <err.h>
44#include <string.h>
45#include "pathnames.h"
46#include "apm-proto.h"
47
48#define FALSE0 0
49#define TRUE1 1
50
51extern char *__progname;
52
53static int do_zzz(int, enum apm_action);
54static int open_socket(const char *);
55static int send_command(int, struct apm_command *,
56 struct apm_reply *);
57static __dead__attribute__((__noreturn__)) void usage(void);
58static __dead__attribute__((__noreturn__)) void zzusage(void);
59
60static __dead__attribute__((__noreturn__)) void
61usage(void)
62{
63 fprintf(stderr(&__sF[2]),"usage: %s [-AabHLlmPSvZz] [-f sockname]\n",
64 __progname);
65 exit(1);
66}
67
68static __dead__attribute__((__noreturn__)) void
69zzusage(void)
70{
71 fprintf(stderr(&__sF[2]),"usage: %s [-SZz] [-f sockname]\n",
72 __progname);
73 exit(1);
74}
75
76static int
77send_command(int fd, struct apm_command *cmd, struct apm_reply *reply)
78{
79 /* send a command to the apm daemon */
80 cmd->vno = APMD_VNO4;
81
82 if (send(fd, cmd, sizeof(*cmd), 0) == sizeof(*cmd)) {
17
Assuming the condition is false
18
Taking false branch
83 if (recv(fd, reply, sizeof(*reply), 0) != sizeof(*reply)) {
84 warn("invalid reply from APM daemon");
85 return (1);
86 }
87 } else {
88 warn("invalid send to APM daemon");
89 return (1);
19
Returning without writing to 'reply->error'
90 }
91 return (0);
92}
93
94static int
95do_zzz(int fd, enum apm_action action)
96{
97 struct apm_command command;
98 struct apm_reply reply;
99 char *msg;
100 int ret;
101
102 switch (action) {
14
Control jumps to 'case NONE:' at line 103
103 case NONE:
104 case SUSPEND:
105 command.action = SUSPEND;
106 msg = "Suspending system";
107 break;
15
Execution continues on line 120
108 case STANDBY:
109 command.action = STANDBY;
110 msg = "System standing by";
111 break;
112 case HIBERNATE:
113 command.action = HIBERNATE;
114 msg = "Hibernating system";
115 break;
116 default:
117 zzusage();
118 }
119
120 printf("%s...\n", msg);
121 ret = send_command(fd, &command, &reply);
16
Calling 'send_command'
20
Returning from 'send_command'
122 if (reply.error)
21
Branch condition evaluates to a garbage value
123 errx(1, "%s: %s", apm_state(reply.newstate), strerror(reply.error));
124 exit(ret);
125}
126
127static int
128open_socket(const char *sockname)
129{
130 int sock, errr;
131 struct sockaddr_un s_un;
132
133 sock = socket(AF_UNIX1, SOCK_STREAM1, 0);
134 if (sock == -1)
135 err(1, "cannot create local socket");
136
137 s_un.sun_family = AF_UNIX1;
138 strlcpy(s_un.sun_path, sockname, sizeof(s_un.sun_path));
139 if (connect(sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
140 errr = errno(*__errno());
141 close(sock);
142 errno(*__errno()) = errr;
143 sock = -1;
144 }
145 return (sock);
146}
147
148int
149main(int argc, char *argv[])
150{
151 const char *sockname = _PATH_APM_SOCKET"/var/run/apmdev";
152 int doac = FALSE0;
153 int dopct = FALSE0;
154 int dobstate = FALSE0;
155 int domin = FALSE0;
156 int doperf = FALSE0;
157 int verbose = FALSE0;
158 int ch, fd, rval;
159 enum apm_action action = NONE;
160 struct apm_command command;
161 struct apm_reply reply;
162 int cpuspeed_mib[] = { CTL_HW6, HW_CPUSPEED12 }, cpuspeed;
163 size_t cpuspeed_sz = sizeof(cpuspeed);
164
165 if (sysctl(cpuspeed_mib, 2, &cpuspeed, &cpuspeed_sz, NULL((void *)0), 0) == -1)
1
Assuming the condition is false
2
Taking false branch
166 err(1, "sysctl hw.cpuspeed");
167
168 while ((ch = getopt(argc, argv, "ACHLlmbvaPSzZf:")) != -1) {
3
Assuming the condition is false
4
Loop condition is false. Execution continues on line 245
169 switch (ch) {
170 case 'v':
171 verbose = TRUE1;
172 break;
173 case 'f':
174 sockname = optarg;
175 break;
176 case 'z':
177 if (action != NONE)
178 usage();
179 action = SUSPEND;
180 break;
181 case 'S':
182 if (action != NONE)
183 usage();
184 action = STANDBY;
185 break;
186 case 'Z':
187 if (action != NONE)
188 usage();
189 action = HIBERNATE;
190 break;
191 case 'A':
192 case 'C':
193 if (action != NONE)
194 usage();
195 action = SETPERF_AUTO;
196 break;
197 case 'H':
198 if (action != NONE)
199 usage();
200 action = SETPERF_HIGH;
201 break;
202 case 'L':
203 if (action != NONE)
204 usage();
205 action = SETPERF_LOW;
206 break;
207 case 'b':
208 if (action != NONE && action != GETSTATUS)
209 usage();
210 dobstate = TRUE1;
211 action = GETSTATUS;
212 break;
213 case 'l':
214 if (action != NONE && action != GETSTATUS)
215 usage();
216 dopct = TRUE1;
217 action = GETSTATUS;
218 break;
219 case 'm':
220 if (action != NONE && action != GETSTATUS)
221 usage();
222 domin = TRUE1;
223 action = GETSTATUS;
224 break;
225 case 'a':
226 if (action != NONE && action != GETSTATUS)
227 usage();
228 doac = TRUE1;
229 action = GETSTATUS;
230 break;
231 case 'P':
232 if (action != NONE && action != GETSTATUS)
233 usage();
234 doperf = TRUE1;
235 action = GETSTATUS;
236 break;
237 default:
238 if (!strcmp(__progname, "zzz") ||
239 !strcmp(__progname, "ZZZ"))
240 zzusage();
241 else
242 usage();
243 }
244 }
245 argc -= optind;
246 argv += optind;
247 if (argc)
5
Assuming 'argc' is 0
6
Taking false branch
248 usage();
249
250 fd = open_socket(sockname);
251
252 if (fd != -1) {
7
Taking true branch
253 if (pledge("stdio", NULL((void *)0)) == -1)
8
Assuming the condition is false
9
Taking false branch
254 err(1, "pledge");
255 }
256
257 if (!strcmp(__progname, "zzz")) {
10
Taking true branch
258 if (fd < 0)
11
Assuming 'fd' is >= 0
12
Taking false branch
259 err(1, "cannot connect to apmd");
260 else
261 return (do_zzz(fd, action));
13
Calling 'do_zzz'
262 } else if (!strcmp(__progname, "ZZZ")) {
263 if (fd < 0)
264 err(1, "cannot connect to apmd");
265 else
266 return (do_zzz(fd, HIBERNATE));
267 }
268
269
270 bzero(&reply, sizeof reply);
271 reply.batterystate.battery_state = APM_BATT_UNKNOWN0xff;
272 reply.batterystate.ac_state = APM_AC_UNKNOWN0xff;
273 reply.perfmode = PERF_MANUAL;
274 reply.cpuspeed = cpuspeed;
275
276 switch (action) {
277 case SETPERF_LOW:
278 case SETPERF_HIGH:
279 case SETPERF_AUTO:
280 if (fd == -1)
281 errx(1, "cannot connect to apmd, "
282 "not changing performance adjustment mode");
283 goto balony;
284 case NONE:
285 action = GETSTATUS;
286 verbose = doac = dopct = dobstate = domin = doperf = TRUE1;
287 /* FALLTHROUGH */
288 case GETSTATUS:
289 if (fd == -1) {
290 /* open the device directly and get status */
291 fd = open(_PATH_APM_NORMAL"/dev/apm", O_RDONLY0x0000);
292 if (ioctl(fd, APM_IOC_GETPOWER((unsigned long)0x40000000 | ((sizeof(struct apm_power_info) &
0x1fff) << 16) | ((('A')) << 8) | ((3)))
,
293 &reply.batterystate) == 0) {
294 if (pledge("stdio", NULL((void *)0)) == -1)
295 err(1, "pledge");
296
297 goto printval;
298 }
299 }
300 /* FALLTHROUGH */
301balony:
302 case SUSPEND:
303 case STANDBY:
304 case HIBERNATE:
305 command.action = action;
306 break;
307 default:
308 usage();
309 }
310
311 if (fd != -1 && (rval = send_command(fd, &command, &reply)) != 0)
312 errx(rval, "cannot get reply from APM daemon");
313
314 switch (action) {
315 case GETSTATUS:
316 printval:
317 if (!verbose) {
318 if (dobstate)
319 printf("%d\n",
320 reply.batterystate.battery_state);
321 if (dopct)
322 printf("%d\n",
323 reply.batterystate.battery_life);
324 if (domin) {
325 if (reply.batterystate.minutes_left ==
326 (u_int)-1)
327 printf("unknown\n");
328 else
329 printf("%d\n",
330 reply.batterystate.minutes_left);
331 }
332 if (doac)
333 printf("%d\n",
334 reply.batterystate.ac_state);
335 if (doperf)
336 printf("%d\n", reply.perfmode);
337 break;
338 }
339
340 if (dobstate) {
341 printf("Battery state: %s",
342 battstate(reply.batterystate.battery_state));
343 if (!dopct && !domin)
344 printf("\n");
345 }
346
347 if (dopct && !dobstate)
348 printf("Battery remaining: %d percent",
349 reply.batterystate.battery_life);
350 else if (dopct)
351 printf(", %d%% remaining",
352 reply.batterystate.battery_life);
353 if (dopct && !domin)
354 printf("\n");
355
356 if (domin && !dobstate && !dopct) {
357#ifdef __powerpc__
358 if (reply.batterystate.battery_state ==
359 APM_BATT_CHARGING0x03)
360 printf("Remaining battery recharge "
361 "time estimate: %d minutes\n",
362 reply.batterystate.minutes_left);
363 else if (reply.batterystate.minutes_left == 0 &&
364 reply.batterystate.battery_life > 10)
365 printf("Battery life estimate: "
366 "not available\n");
367 else
368#endif
369 {
370 printf("Battery life estimate: ");
371 if (reply.batterystate.minutes_left ==
372 (u_int)-1)
373 printf("unknown\n");
374 else
375 printf("%d minutes\n",
376 reply.batterystate.minutes_left);
377 }
378 } else if (domin) {
379#ifdef __powerpc__
380 if (reply.batterystate.battery_state ==
381 APM_BATT_CHARGING0x03)
382 printf(", %d minutes recharge time estimate\n",
383 reply.batterystate.minutes_left);
384 else if (reply.batterystate.minutes_left == 0 &&
385 reply.batterystate.battery_life > 10)
386 printf(", unknown life estimate\n");
387 else
388#endif
389 {
390 if (reply.batterystate.minutes_left ==
391 (u_int)-1)
392 printf(", unknown");
393 else
394 printf(", %d minutes",
395 reply.batterystate.minutes_left);
396 printf(" life estimate\n");
397 }
398 }
399
400 if (doac)
401 printf("A/C adapter state: %s\n",
402 ac_state(reply.batterystate.ac_state));
403
404 if (doperf)
405 printf("Performance adjustment mode: %s (%d MHz)\n",
406 perf_mode(reply.perfmode), reply.cpuspeed);
407 break;
408 default:
409 break;
410 }
411
412 switch (reply.newstate) {
413 case SUSPEND:
414 printf("System will enter suspend mode momentarily.\n");
415 break;
416 case STANDBY:
417 printf("System will enter standby mode momentarily.\n");
418 break;
419 case HIBERNATE:
420 printf("System will enter hibernate mode momentarily.\n");
421 break;
422 default:
423 break;
424 }
425 if (reply.error)
426 errx(1, "%s: %s", apm_state(reply.newstate), strerror(reply.error));
427 return (0);
428}