Bug Summary

File:src/libexec/ftpd/popen.c
Warning:line 131, column 10
Potential memory leak

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 popen.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/libexec/ftpd/obj -resource-dir /usr/local/lib/clang/13.0.0 -I /usr/src/libexec/ftpd -I /usr/src/libexec/ftpd/../../bin/ls -internal-isystem /usr/local/lib/clang/13.0.0/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/libexec/ftpd/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/libexec/ftpd/popen.c
1/* $OpenBSD: popen.c,v 1.30 2020/12/27 15:11:04 florian Exp $ */
2/* $NetBSD: popen.c,v 1.5 1995/04/11 02:45:00 cgd Exp $ */
3
4/*
5 * Copyright (c) 1988, 1993, 1994
6 * The Regents of the University of California. All rights reserved.
7 *
8 * This code is derived from software written by Ken Arnold and
9 * published in UNIX Review, Vol. 6, No. 8.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * 3. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * SUCH DAMAGE.
34 *
35 */
36
37#include <sys/types.h>
38#include <sys/wait.h>
39
40#include <errno(*__errno()).h>
41#include <glob.h>
42#include <limits.h>
43#include <signal.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <syslog.h>
48#include <unistd.h>
49
50#include <netinet/in.h>
51
52#include "monitor.h"
53#include "extern.h"
54
55/*
56 * Special version of popen which avoids call to shell. This ensures no one
57 * may create a pipe to a hidden program as a side effect of a list or dir
58 * command.
59 */
60
61FILE *
62ftpd_ls(const char *path, pid_t *pidptr)
63{
64 char *cp;
65 FILE *iop;
66 int argc = 0, pdes[2];
67 pid_t pid;
68 char **pop, *argv[_POSIX_ARG_MAX4096];
69
70 if (pipe(pdes) == -1)
1
Assuming the condition is false
2
Taking false branch
71 return (NULL((void *)0));
72
73 /* break up string into pieces */
74 argv[argc++] = "/bin/ls";
75 argv[argc++] = "-lgA";
76 argv[argc++] = "--";
77
78 /* glob that path */
79 if (path != NULL((void *)0)) {
3
Assuming 'path' is not equal to NULL
4
Taking true branch
80 glob_t gl;
81
82 memset(&gl, 0, sizeof(gl));
83 if (glob(path,
5
Assuming the condition is false
6
Taking false branch
84 GLOB_BRACE0x0080|GLOB_NOCHECK0x0010|GLOB_QUOTE0x0400|GLOB_TILDE0x0800|GLOB_LIMIT0x2000,
85 NULL((void *)0), &gl)) {
86 fatal ("Glob error.");
87 } else if (gl.gl_pathc > 0) {
7
Assuming field 'gl_pathc' is > 0
8
Taking true branch
88 for (pop = gl.gl_pathv; *pop && argc < _POSIX_ARG_MAX4096-1;
9
Assuming the condition is true
10
Loop condition is true. Entering loop body
13
Assuming the condition is true
14
Loop condition is true. Entering loop body
18
Assuming the condition is false
89 pop++) {
90 argv[argc++] = strdup(*pop);
15
Memory is allocated
91 if (argv[argc - 1] == NULL((void *)0))
11
Assuming the condition is true
12
Taking true branch
16
Assuming the condition is false
17
Taking false branch
92 fatal ("Out of memory.");
93 }
94 }
95 globfree(&gl);
96 }
97 argv[argc] = NULL((void *)0);
98
99 iop = NULL((void *)0);
100
101 switch (pid = fork()) {
19
Control jumps to 'case -1:' at line 102
102 case -1: /* error */
103 (void)close(pdes[0]);
104 (void)close(pdes[1]);
105 goto pfree;
20
Control jumps to line 128
106 /* NOTREACHED */
107 case 0: /* child */
108 if (pdes[1] != STDOUT_FILENO1) {
109 dup2(pdes[1], STDOUT_FILENO1);
110 (void)close(pdes[1]);
111 }
112 dup2(STDOUT_FILENO1, STDERR_FILENO2); /* stderr too! */
113 (void)close(pdes[0]);
114 closelog();
115
116 extern int ls_main(int, char **);
117
118 /* reset getopt for ls_main */
119 optreset = optind = 1;
120 exit(ls_main(argc, argv));
121 }
122 /* parent; assume fdopen can't fail... */
123 iop = fdopen(pdes[0], "r");
124 (void)close(pdes[1]);
125 *pidptr = pid;
126
127 pfree:
128 for (argc = 3; argv[argc] != NULL((void *)0); argc++)
21
Loop condition is false. Execution continues on line 131
129 free(argv[argc]);
130
131 return (iop);
22
Potential memory leak
132}
133
134int
135ftpd_pclose(FILE *iop, pid_t pid)
136{
137 int status;
138 pid_t rv;
139 sigset_t sigset, osigset;
140
141 (void)fclose(iop);
142 sigemptyset(&sigset);
143 sigaddset(&sigset, SIGINT2);
144 sigaddset(&sigset, SIGQUIT3);
145 sigaddset(&sigset, SIGHUP1);
146 sigprocmask(SIG_BLOCK1, &sigset, &osigset);
147 while ((rv = waitpid(pid, &status, 0)) == -1 && errno(*__errno()) == EINTR4)
148 continue;
149 sigprocmask(SIG_SETMASK3, &osigset, NULL((void *)0));
150 if (rv == -1)
151 return (-1);
152 if (WIFEXITED(status)(((status) & 0177) == 0))
153 return (WEXITSTATUS(status)(int)(((unsigned)(status) >> 8) & 0xff));
154 return (1);
155}