Bug Summary

File:src/bin/ps/ps.c
Warning:line 613, column 17
Use of memory allocated with size zero

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple amd64-unknown-openbsd7.4 -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name ps.c -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 -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -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/bin/ps/obj -resource-dir /usr/local/llvm16/lib/clang/16 -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/bin/ps/obj -ferror-limit 19 -fwrapv -D_RET_PROTECTOR -ret-protector -fcf-protection=branch -fno-jump-tables -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/scan/2024-01-11-140451-98009-1 -x c /usr/src/bin/ps/ps.c
1/* $OpenBSD: ps.c,v 1.80 2023/11/10 09:17:02 kn Exp $ */
2/* $NetBSD: ps.c,v 1.15 1995/05/18 20:33:25 mycroft Exp $ */
3
4/*-
5 * Copyright (c) 1990, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the University nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 */
32
33#include <sys/param.h> /* NODEV */
34#include <sys/types.h>
35#include <sys/signal.h>
36#include <sys/sysctl.h>
37#include <sys/time.h>
38#include <sys/resource.h>
39#include <sys/proc.h>
40#include <sys/stat.h>
41#include <sys/ioctl.h>
42
43#include <ctype.h>
44#include <err.h>
45#include <errno(*__errno()).h>
46#include <fcntl.h>
47#include <kvm.h>
48#include <locale.h>
49#include <nlist.h>
50#include <paths.h>
51#include <pwd.h>
52#include <stdio.h>
53#include <stdlib.h>
54#include <string.h>
55#include <unistd.h>
56#include <limits.h>
57
58#include "ps.h"
59
60extern char *__progname;
61
62struct varent *vhead;
63
64int eval; /* exit value */
65int sumrusage; /* -S */
66int termwidth; /* width of screen (0 == infinity) */
67int totwidth; /* calculated width of requested variables */
68
69int needcomm, needenv, neednlist, commandonly;
70
71enum sort { DEFAULT, SORTMEM, SORTCPU } sortby = DEFAULT;
72
73static char *kludge_oldps_options(char *);
74static int pscomp(const void *, const void *);
75static void scanvars(void);
76static void forest_sort(struct pinfo *, int);
77static void usage(void);
78
79char dfmt[] = "pid tt state time command";
80char tfmt[] = "pid tid tt state time command";
81char jfmt[] = "user pid ppid pgid sess jobc state tt time command";
82char lfmt[] = "uid pid ppid cpu pri nice vsz rss wchan state tt time command";
83char o1[] = "pid";
84char o2[] = "tt state time command";
85char ufmt[] = "user pid %cpu %mem vsz rss tt state start time command";
86char vfmt[] = "pid state time sl re pagein vsz rss lim tsiz %cpu %mem command";
87
88kvm_t *kd;
89int kvm_sysctl_only;
90
91int
92main(int argc, char *argv[])
93{
94 struct kinfo_proc *kp;
95 struct pinfo *pinfo;
96 struct varent *vent;
97 struct winsize ws;
98 dev_t ttydev;
99 pid_t pid;
100 uid_t uid;
101 int all, ch, flag, i, fmt, lineno, nentries;
102 int prtheader, showthreads, wflag, kflag, what, Uflag, xflg;
103 int forest;
104 char *nlistf, *memf, *swapf, *cols, errbuf[_POSIX2_LINE_MAX2048];
105
106 setlocale(LC_CTYPE2, "");
107
108 termwidth = 0;
109 if ((cols = getenv("COLUMNS")) != NULL((void *)0))
110 termwidth = strtonum(cols, 1, INT_MAX0x7fffffff, NULL((void *)0));
111 if (termwidth == 0 &&
112 (ioctl(STDOUT_FILENO1, TIOCGWINSZ((unsigned long)0x40000000 | ((sizeof(struct winsize) & 0x1fff
) << 16) | ((('t')) << 8) | ((104)))
, &ws) == 0 ||
113 ioctl(STDERR_FILENO2, TIOCGWINSZ((unsigned long)0x40000000 | ((sizeof(struct winsize) & 0x1fff
) << 16) | ((('t')) << 8) | ((104)))
, &ws) == 0 ||
114 ioctl(STDIN_FILENO0, TIOCGWINSZ((unsigned long)0x40000000 | ((sizeof(struct winsize) & 0x1fff
) << 16) | ((('t')) << 8) | ((104)))
, &ws) == 0) &&
115 ws.ws_col > 0)
116 termwidth = ws.ws_col - 1;
117 if (termwidth == 0)
118 termwidth = 79;
119
120 if (argc > 1)
121 argv[1] = kludge_oldps_options(argv[1]);
122
123 all = fmt = prtheader = showthreads = wflag = kflag = Uflag = xflg = 0;
124 pid = -1;
125 uid = 0;
126 forest = 0;
127 ttydev = NODEV(dev_t)(-1);
128 memf = nlistf = swapf = NULL((void *)0);
129 while ((ch = getopt(argc, argv,
130 "AaCcefgHhjkLlM:mN:O:o:p:rSTt:U:uvW:wx")) != -1)
131 switch (ch) {
132 case 'A':
133 all = 1;
134 xflg = 1;
135 break;
136 case 'a':
137 all = 1;
138 break;
139 case 'C':
140 break; /* no-op */
141 case 'c':
142 commandonly = 1;
143 break;
144 case 'e': /* XXX set ufmt */
145 needenv = 1;
146 break;
147 case 'f':
148 forest = 1;
149 break;
150 case 'g':
151 break; /* no-op */
152 case 'H':
153 showthreads = 1;
154 break;
155 case 'h':
156 prtheader = ws.ws_row > 5 ? ws.ws_row : 22;
157 break;
158 case 'j':
159 parsefmt(jfmt);
160 fmt = 1;
161 jfmt[0] = '\0';
162 break;
163 case 'k':
164 kflag = 1;
165 break;
166 case 'L':
167 showkey();
168 exit(0);
169 case 'l':
170 parsefmt(lfmt);
171 fmt = 1;
172 lfmt[0] = '\0';
173 break;
174 case 'M':
175 memf = optarg;
176 break;
177 case 'm':
178 sortby = SORTMEM;
179 break;
180 case 'N':
181 nlistf = optarg;
182 break;
183 case 'O':
184 parsefmt(o1);
185 parsefmt(optarg);
186 parsefmt(o2);
187 o1[0] = o2[0] = '\0';
188 fmt = 1;
189 break;
190 case 'o':
191 parsefmt(optarg);
192 fmt = 1;
193 break;
194 case 'p':
195 pid = atol(optarg);
196 xflg = 1;
197 break;
198 case 'r':
199 sortby = SORTCPU;
200 break;
201 case 'S':
202 sumrusage = 1;
203 break;
204 case 'T':
205 if ((optarg = ttyname(STDIN_FILENO0)) == NULL((void *)0))
206 errx(1, "stdin: not a terminal");
207 /* FALLTHROUGH */
208 case 't': {
209 struct stat sb;
210 char *ttypath, pathbuf[PATH_MAX1024];
211
212 if (strcmp(optarg, "co") == 0)
213 ttypath = _PATH_CONSOLE"/dev/console";
214 else if (*optarg != '/') {
215 int r = snprintf(pathbuf, sizeof(pathbuf), "%s%s",
216 _PATH_TTY"/dev/tty", optarg);
217 if (r < 0 || r > sizeof(pathbuf))
218 errx(1, "%s: too long\n", optarg);
219 ttypath = pathbuf;
220 } else
221 ttypath = optarg;
222 if (stat(ttypath, &sb) == -1)
223 err(1, "%s", ttypath);
224 if (!S_ISCHR(sb.st_mode)((sb.st_mode & 0170000) == 0020000))
225 errx(1, "%s: not a terminal", ttypath);
226 ttydev = sb.st_rdev;
227 break;
228 }
229 case 'U': {
230 int found = 0;
231
232 if (uid_from_user(optarg, &uid) == 0)
233 found = 1;
234 else {
235 const char *errstr;
236
237 uid = strtonum(optarg, 0, UID_MAX0xffffffffU, &errstr);
238 if (errstr == NULL((void *)0) &&
239 user_from_uid(uid, 1) != NULL((void *)0))
240 found = 1;
241 }
242 if (!found)
243 errx(1, "%s: unknown user", optarg);
244 Uflag = xflg = 1;
245 break;
246 }
247 case 'u':
248 parsefmt(ufmt);
249 sortby = SORTCPU;
250 fmt = 1;
251 ufmt[0] = '\0';
252 break;
253 case 'v':
254 parsefmt(vfmt);
255 sortby = SORTMEM;
256 fmt = 1;
257 vfmt[0] = '\0';
258 break;
259 case 'W':
260 swapf = optarg;
261 break;
262 case 'w':
263 if (wflag)
264 termwidth = UNLIMITED0;
265 else if (termwidth < 131)
266 termwidth = 131;
267 wflag = 1;
268 break;
269 case 'x':
270 xflg = 1;
271 break;
272 default:
273 usage();
274 }
275 argc -= optind;
276 argv += optind;
277
278#define BACKWARD_COMPATIBILITY
279#ifdef BACKWARD_COMPATIBILITY
280 if (*argv) {
281 nlistf = *argv;
282 if (*++argv) {
283 memf = *argv;
284 if (*++argv)
285 swapf = *argv;
286 }
287 }
288#endif
289
290 if (nlistf == NULL((void *)0) && memf == NULL((void *)0) && swapf == NULL((void *)0)) {
291 kd = kvm_openfiles(NULL((void *)0), NULL((void *)0), NULL((void *)0), KVM_NO_FILES0x80000000, errbuf);
292 kvm_sysctl_only = 1;
293 } else {
294 kd = kvm_openfiles(nlistf, memf, swapf, O_RDONLY0x0000, errbuf);
295 }
296 if (kd == NULL((void *)0))
297 errx(1, "%s", errbuf);
298
299 if (unveil(_PATH_DEVDB"/var/run/dev.db", "r") == -1 && errno(*__errno()) != ENOENT2)
300 err(1, "unveil %s", _PATH_DEVDB"/var/run/dev.db");
301 if (unveil(_PATH_DEV"/dev/", "r") == -1 && errno(*__errno()) != ENOENT2)
302 err(1, "unveil %s", _PATH_DEV"/dev/");
303 if (swapf)
304 if (unveil(swapf, "r") == -1)
305 err(1, "unveil %s", swapf);
306 if (nlistf)
307 if (unveil(nlistf, "r") == -1)
308 err(1, "unveil %s", nlistf);
309 if (memf)
310 if (unveil(memf, "r") == -1)
311 err(1, "unveil %s", memf);
312 if (pledge("stdio rpath getpw ps", NULL((void *)0)) == -1)
313 err(1, "pledge");
314
315 if (!fmt) {
316 if (showthreads)
317 parsefmt(tfmt);
318 else
319 parsefmt(dfmt);
320 }
321
322 /* XXX - should be cleaner */
323 if (!all && ttydev == NODEV(dev_t)(-1) && pid == -1 && !Uflag) {
324 uid = getuid();
325 Uflag = 1;
326 }
327
328 /*
329 * scan requested variables, noting what structures are needed,
330 * and adjusting header widths as appropriate.
331 */
332 scanvars();
333
334 if (neednlist && !nlistread)
335 (void) donlist();
336
337 /*
338 * get proc list
339 */
340 if (Uflag) {
341 what = KERN_PROC_UID5;
342 flag = uid;
343 } else if (ttydev != NODEV(dev_t)(-1)) {
344 what = KERN_PROC_TTY4;
345 flag = ttydev;
346 } else if (pid != -1) {
347 what = KERN_PROC_PID1;
348 flag = pid;
349 } else if (kflag) {
350 what = KERN_PROC_KTHREAD7;
351 flag = 0;
352 } else {
353 what = KERN_PROC_ALL0;
354 flag = 0;
355 }
356 if (showthreads)
357 what |= KERN_PROC_SHOW_THREADS0x40000000;
358
359 /*
360 * select procs
361 */
362 kp = kvm_getprocs(kd, what, flag, sizeof(*kp), &nentries);
363 if (kp == NULL((void *)0))
364 errx(1, "%s", kvm_geterr(kd));
365
366 /*
367 * print header
368 */
369 printheader();
370 if (nentries == 0)
371 exit(1);
372
373 if ((pinfo = calloc(nentries, sizeof(struct pinfo))) == NULL((void *)0))
374 err(1, NULL((void *)0));
375 for (i = 0; i < nentries; i++)
376 pinfo[i].ki = &kp[i];
377 qsort(pinfo, nentries, sizeof(struct pinfo), pscomp);
378
379 if (forest)
380 forest_sort(pinfo, nentries);
381
382 /*
383 * for each proc, call each variable output function.
384 */
385 for (i = lineno = 0; i < nentries; i++) {
386 if (xflg == 0 && ((int)pinfo[i].ki->p_tdev == NODEV(dev_t)(-1) ||
387 (pinfo[i].ki->p_psflags & PS_CONTROLT0x00000001 ) == 0))
388 continue;
389 if (showthreads && pinfo[i].ki->p_tid == -1)
390 continue;
391 for (vent = vhead; vent; vent = vent->next) {
392 (vent->var->oproc)(&pinfo[i], vent);
393 if (vent->next != NULL((void *)0))
394 (void)putchar(' ')(!__isthreaded ? __sputc(' ', (&__sF[1])) : (putc)(' ', (
&__sF[1])))
;
395 }
396 (void)putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
397 if (prtheader && lineno++ == prtheader - 4) {
398 (void)putchar('\n')(!__isthreaded ? __sputc('\n', (&__sF[1])) : (putc)('\n',
(&__sF[1])))
;
399 printheader();
400 lineno = 0;
401 }
402 }
403 exit(eval);
404}
405
406static void
407scanvars(void)
408{
409 struct varent *vent;
410 VAR *v;
411 int i;
412
413 for (vent = vhead; vent; vent = vent->next) {
414 v = vent->var;
415 i = strlen(v->header);
416 if (v->width < i)
417 v->width = i;
418 totwidth += v->width + 1; /* +1 for space */
419 if (v->flag & COMM0x01)
420 needcomm = 1;
421 if (v->flag & NLIST0x10)
422 neednlist = 1;
423 }
424 totwidth--;
425}
426
427static int
428pscomp(const void *v1, const void *v2)
429{
430 const struct pinfo *p1 = (const struct pinfo *)v1;
431 const struct pinfo *p2 = (const struct pinfo *)v2;
432 const struct kinfo_proc *kp1 = p1->ki;
433 const struct kinfo_proc *kp2 = p2->ki;
434 int i;
435#define VSIZE(k)((k)->p_vm_dsize + (k)->p_vm_ssize + (k)->p_vm_tsize
)
((k)->p_vm_dsize + (k)->p_vm_ssize + (k)->p_vm_tsize)
436
437 if (sortby == SORTCPU && (i = getpcpu(kp2) - getpcpu(kp1)) != 0)
438 return (i);
439 if (sortby == SORTMEM && (i = VSIZE(kp2)((kp2)->p_vm_dsize + (kp2)->p_vm_ssize + (kp2)->p_vm_tsize
)
- VSIZE(kp1)((kp1)->p_vm_dsize + (kp1)->p_vm_ssize + (kp1)->p_vm_tsize
)
) != 0)
440 return (i);
441 if ((i = kp1->p_tdev - kp2->p_tdev) == 0 &&
442 (i = kp1->p_ustart_sec - kp2->p_ustart_sec) == 0)
443 i = kp1->p_ustart_usec - kp2->p_ustart_usec;
444 return (i);
445}
446
447/*
448 * ICK (all for getopt), would rather hide the ugliness
449 * here than taint the main code.
450 *
451 * ps foo -> ps -foo
452 * ps 34 -> ps -p34
453 *
454 * The old convention that 't' with no trailing tty arg means the users
455 * tty, is only supported if argv[1] doesn't begin with a '-'. This same
456 * feature is available with the option 'T', which takes no argument.
457 */
458static char *
459kludge_oldps_options(char *s)
460{
461 size_t len;
462 char *newopts, *ns, *cp;
463
464 len = strlen(s);
465 if ((newopts = ns = malloc(2 + len + 1)) == NULL((void *)0))
466 err(1, NULL((void *)0));
467 /*
468 * options begin with '-'
469 */
470 if (*s != '-')
471 *ns++ = '-'; /* add option flag */
472
473 /*
474 * gaze to end of argv[1]
475 */
476 cp = s + len - 1;
477 /*
478 * if last letter is a 't' flag with no argument (in the context
479 * of the oldps options -- option string NOT starting with a '-' --
480 * then convert to 'T' (meaning *this* terminal, i.e. ttyname(0)).
481 */
482 if (*cp == 't' && *s != '-')
483 *cp = 'T';
484 else {
485 /*
486 * otherwise check for trailing number, which *may* be a
487 * pid.
488 */
489 while (cp >= s && isdigit((unsigned char)*cp))
490 --cp;
491 }
492 cp++;
493 memmove(ns, s, (size_t)(cp - s)); /* copy up to trailing number */
494 ns += cp - s;
495 /*
496 * if there's a trailing number, and not a preceding 'p' (pid),
497 * 't' (tty) or 'U' (user) flag,
498 * then assume it's a pid and insert a 'p' flag.
499 */
500 if (isdigit((unsigned char)*cp) &&
501 (cp == s || (cp[-1] != 't' && cp[-1] != 'p' && cp[-1] != 'U' &&
502 (cp - 1 == s || cp[-2] != 't'))))
503 *ns++ = 'p';
504 /* and append the number */
505 (void)strlcpy(ns, cp, newopts + len + 3 - ns);
506
507 return (newopts);
508}
509
510static void
511forest_sort(struct pinfo *ki, int items)
512{
513 int dst, lvl, maxlvl, n, ndst, nsrc, siblings, src;
514 unsigned char *path;
515 struct pinfo kn;
516
517 /*
518 * First, sort the entries by forest, tracking the forest
519 * depth in the level field.
520 */
521 src = 0;
522 maxlvl = 0;
523 while (src < items) {
1
Assuming 'src' is < 'items'
2
Loop condition is true. Entering loop body
5
Execution continues on line 523
6
Assuming 'src' is >= 'items'
7
Loop condition is false. Execution continues on line 582
524 if (ki[src].level) {
3
Assuming field 'level' is not equal to 0
4
Taking true branch
525 src++;
526 continue;
527 }
528 for (nsrc = 1; src + nsrc < items; nsrc++)
529 if (!ki[src + nsrc].level)
530 break;
531
532 for (dst = 0; dst < items; dst++) {
533 if (ki[dst].ki->p_pid == ki[src].ki->p_pid)
534 continue;
535 if (ki[dst].ki->p_pid == ki[src].ki->p_ppid)
536 break;
537 }
538
539 if (dst == items) {
540 src += nsrc;
541 continue;
542 }
543
544 for (ndst = 1; dst + ndst < items; ndst++)
545 if (ki[dst + ndst].level <= ki[dst].level)
546 break;
547
548 for (n = src; n < src + nsrc; n++) {
549 ki[n].level += ki[dst].level + 1;
550 if (maxlvl < ki[n].level)
551 maxlvl = ki[n].level;
552 }
553
554 while (nsrc) {
555 if (src < dst) {
556 kn = ki[src];
557 memmove(ki + src, ki + src + 1,
558 (dst - src + ndst - 1) * sizeof *ki);
559 ki[dst + ndst - 1] = kn;
560 nsrc--;
561 dst--;
562 ndst++;
563 } else if (src != dst + ndst) {
564 kn = ki[src];
565 memmove(ki + dst + ndst + 1, ki + dst + ndst,
566 (src - dst - ndst) * sizeof *ki);
567 ki[dst + ndst] = kn;
568 ndst++;
569 nsrc--;
570 src++;
571 } else {
572 ndst += nsrc;
573 src += nsrc;
574 nsrc = 0;
575 }
576 }
577 }
578 /*
579 * Now populate prefix (instead of level) with the command
580 * prefix used to show descendancies.
581 */
582 path = calloc(1, (maxlvl + 7) / 8);
8
Memory is allocated
583 if (path == NULL((void *)0))
9
Assuming 'path' is not equal to NULL
10
Taking false branch
584 err(1, NULL((void *)0));
585
586 for (src = 0; src < items; src++) {
11
Loop condition is true. Entering loop body
587 if ((lvl = ki[src].level) == 0) {
12
Taking false branch
588 ki[src].prefix = NULL((void *)0);
589 continue;
590 }
591
592 if ((ki[src].prefix = malloc(lvl * 2 + 1)) == NULL((void *)0))
13
Assuming the condition is false
14
Taking false branch
593 err(1, NULL((void *)0));
594
595 for (n = 0; n < lvl - 2; n++) {
15
Assuming the condition is false
16
Loop condition is false. Execution continues on line 601
596 ki[src].prefix[n * 2] =
597 path[n / 8] & 1 << (n % 8) ? '|' : ' ';
598 ki[src].prefix[n * 2 + 1] = ' ';
599
600 }
601 if (n == lvl - 2) {
17
Assuming the condition is true
18
Taking true branch
602 /* Have I any more siblings? */
603 for (siblings = 0, dst = src + 1; dst < items; dst++) {
19
Loop condition is false. Execution continues on line 610
604 if (ki[dst].level > lvl)
605 continue;
606 if (ki[dst].level == lvl)
607 siblings = 1;
608 break;
609 }
610 if (siblings
19.1
'siblings' is 0
)
20
Taking false branch
611 path[n / 8] |= 1 << (n % 8);
612 else
613 path[n / 8] &= ~(1 << (n % 8));
21
Use of memory allocated with size zero
614 ki[src].prefix[n * 2] = siblings ? '|' : '`';
615 ki[src].prefix[n * 2 + 1] = '-';
616 n++;
617 }
618 strlcpy(ki[src].prefix + n * 2, "- ", (lvl - n) * 2 + 1);
619 }
620 free(path);
621}
622
623static void
624usage(void)
625{
626 fprintf(stderr(&__sF[2]), "usage: %s [-AacefHhjkLlmrSTuvwx] [-M core] [-N system]"
627 " [-O fmt] [-o fmt] [-p pid]\n", __progname);
628 fprintf(stderr(&__sF[2]), "%-*s[-t tty] [-U user] [-W swap]\n",
629 (int)strlen(__progname) + 8, "");
630 exit(1);
631}