Bug Summary

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

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 popen.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/libexec/ftpd/obj -resource-dir /usr/local/llvm16/lib/clang/16 -I /usr/src/libexec/ftpd -I /usr/src/libexec/ftpd/../../bin/ls -internal-isystem /usr/local/llvm16/lib/clang/16/include -internal-externc-isystem /usr/include -O2 -fdebug-compilation-dir=/usr/src/libexec/ftpd/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/libexec/ftpd/popen.c
1/* $OpenBSD: popen.c,v 1.31 2023/02/17 17:59:36 miod 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 FILE *iop;
65 int argc = 0, pdes[2];
66 pid_t pid;
67 char **pop, *argv[_POSIX_ARG_MAX4096];
68
69 if (pipe(pdes) == -1)
1
Assuming the condition is false
2
Taking false branch
70 return (NULL((void *)0));
71
72 /* break up string into pieces */
73 argv[argc++] = "/bin/ls";
74 argv[argc++] = "-lgA";
75 argv[argc++] = "--";
76
77 /* glob that path */
78 if (path != NULL((void *)0)) {
3
Assuming 'path' is not equal to NULL
4
Taking true branch
79 glob_t gl;
80
81 memset(&gl, 0, sizeof(gl));
82 if (glob(path,
5
Assuming the condition is false
6
Taking false branch
83 GLOB_BRACE0x0080|GLOB_NOCHECK0x0010|GLOB_QUOTE0x0400|GLOB_TILDE0x0800|GLOB_LIMIT0x2000,
84 NULL((void *)0), &gl)) {
85 fatal ("Glob error.");
86 } else if (gl.gl_pathc > 0) {
7
Assuming field 'gl_pathc' is > 0
8
Taking true branch
87 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
88 pop++) {
89 argv[argc++] = strdup(*pop);
15
Memory is allocated
90 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
91 fatal ("Out of memory.");
92 }
93 }
94 globfree(&gl);
95 }
96 argv[argc] = NULL((void *)0);
97
98 iop = NULL((void *)0);
99
100 switch (pid = fork()) {
19
Control jumps to 'case -1:' at line 101
101 case -1: /* error */
102 (void)close(pdes[0]);
103 (void)close(pdes[1]);
104 goto pfree;
20
Control jumps to line 127
105 /* NOTREACHED */
106 case 0: /* child */
107 if (pdes[1] != STDOUT_FILENO1) {
108 dup2(pdes[1], STDOUT_FILENO1);
109 (void)close(pdes[1]);
110 }
111 dup2(STDOUT_FILENO1, STDERR_FILENO2); /* stderr too! */
112 (void)close(pdes[0]);
113 closelog();
114
115 extern int ls_main(int, char **);
116
117 /* reset getopt for ls_main */
118 optreset = optind = 1;
119 exit(ls_main(argc, argv));
120 }
121 /* parent; assume fdopen can't fail... */
122 iop = fdopen(pdes[0], "r");
123 (void)close(pdes[1]);
124 *pidptr = pid;
125
126 pfree:
127 for (argc = 3; argv[argc] != NULL((void *)0); argc++)
21
Loop condition is false. Execution continues on line 130
128 free(argv[argc]);
129
130 return (iop);
22
Potential memory leak
131}
132
133int
134ftpd_pclose(FILE *iop, pid_t pid)
135{
136 int status;
137 pid_t rv;
138 sigset_t sigset, osigset;
139
140 (void)fclose(iop);
141 sigemptyset(&sigset);
142 sigaddset(&sigset, SIGINT2);
143 sigaddset(&sigset, SIGQUIT3);
144 sigaddset(&sigset, SIGHUP1);
145 sigprocmask(SIG_BLOCK1, &sigset, &osigset);
146 while ((rv = waitpid(pid, &status, 0)) == -1 && errno(*__errno()) == EINTR4)
147 continue;
148 sigprocmask(SIG_SETMASK3, &osigset, NULL((void *)0));
149 if (rv == -1)
150 return (-1);
151 if (WIFEXITED(status)(((status) & 0177) == 0))
152 return (WEXITSTATUS(status)(int)(((unsigned)(status) >> 8) & 0xff));
153 return (1);
154}