Bug Summary

File:src/usr.bin/rsync/fargs.c
Warning:line 83, column 3
Potential leak of memory pointed to by 'arg'

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 fargs.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/usr.bin/rsync/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/usr.bin/rsync/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/usr.bin/rsync/fargs.c
1/* $OpenBSD: fargs.c,v 1.26 2023/11/27 11:30:49 claudio Exp $ */
2/*
3 * Copyright (c) 2019 Kristaps Dzonsons <kristaps@bsd.lv>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17#include <sys/stat.h>
18
19#include <assert.h>
20#include <err.h>
21#include <stdint.h>
22#include <stdlib.h>
23#include <string.h>
24
25#include "extern.h"
26
27#define RSYNC_PATH"rsync" "rsync"
28
29const char *
30alt_base_mode(int mode)
31{
32 switch (mode) {
33 case BASE_MODE_COMPARE1:
34 return "--compare-dest";
35 case BASE_MODE_COPY2:
36 return "--copy-dest";
37 case BASE_MODE_LINK3:
38 return "--link-dest";
39 default:
40 errx(1, "unknown base mode %d", mode);
41 }
42}
43
44char **
45fargs_cmdline(struct sess *sess, const struct fargs *f, size_t *skip)
46{
47 arglist args;
48 size_t j;
49 char *rsync_path, *ap, *arg;
50
51 memset(&args, 0, sizeof args);
52
53 assert(f != NULL)((f != ((void *)0)) ? (void)0 : __assert2("/usr/src/usr.bin/rsync/fargs.c"
, 53, __func__, "f != NULL"))
;
1
Assuming 'f' is not equal to null
2
'?' condition is true
54 assert(f->sourcesz > 0)((f->sourcesz > 0) ? (void)0 : __assert2("/usr/src/usr.bin/rsync/fargs.c"
, 54, __func__, "f->sourcesz > 0"))
;
3
Assuming field 'sourcesz' is > 0
4
'?' condition is true
55
56 if ((rsync_path = sess->opts->rsync_path) == NULL((void *)0))
5
Assuming the condition is false
6
Taking false branch
57 rsync_path = RSYNC_PATH"rsync";
58
59 if (f->host != NULL((void *)0)) {
7
Assuming field 'host' is not equal to NULL
8
Taking true branch
60 /*
61 * Splice arguments from -e "foo bar baz" into array
62 * elements required for execve(2).
63 * This doesn't do anything fancy: it splits along
64 * whitespace into the array.
65 */
66
67 if (sess->opts->ssh_prog) {
9
Assuming field 'ssh_prog' is non-null
10
Taking true branch
68 ap = strdup(sess->opts->ssh_prog);
11
Memory is allocated
69 if (ap == NULL((void *)0))
12
Assuming 'ap' is not equal to NULL
13
Taking false branch
70 err(ERR_NOMEM22, NULL((void *)0));
71
72 while ((arg = strsep(&ap, " \t")) != NULL((void *)0)) {
14
Loop condition is true. Entering loop body
17
Execution continues on line 72
18
Assuming the condition is false
19
Loop condition is false. Execution continues on line 83
73 if (arg[0] == '\0') {
15
Assuming the condition is true
16
Taking true branch
74 ap++; /* skip separators */
75 continue;
76 }
77
78 addargs(&args, "%s", arg);
79 }
80 } else
81 addargs(&args, "ssh");
82
83 addargs(&args, "%s", f->host);
20
Potential leak of memory pointed to by 'arg'
84 addargs(&args, "%s", rsync_path);
85 if (skip)
86 *skip = args.num;
87 addargs(&args, "--server");
88 if (f->mode == FARGS_RECEIVER)
89 addargs(&args, "--sender");
90 } else {
91 addargs(&args, "%s", rsync_path);
92 addargs(&args, "--server");
93 }
94
95 /* Shared arguments. */
96
97 if (sess->opts->del)
98 addargs(&args, "--delete");
99 if (sess->opts->numeric_ids)
100 addargs(&args, "--numeric-ids");
101 if (sess->opts->preserve_gids)
102 addargs(&args, "-g");
103 if (sess->opts->preserve_links)
104 addargs(&args, "-l");
105 if (sess->opts->dry_run)
106 addargs(&args, "-n");
107 if (sess->opts->preserve_uids)
108 addargs(&args, "-o");
109 if (sess->opts->preserve_perms)
110 addargs(&args, "-p");
111 if (sess->opts->devices)
112 addargs(&args, "-D");
113 if (sess->opts->recursive)
114 addargs(&args, "-r");
115 if (sess->opts->preserve_times)
116 addargs(&args, "-t");
117 if (sess->opts->ignore_times)
118 addargs(&args, "-I");
119 if (verbose > 3)
120 addargs(&args, "-v");
121 if (verbose > 2)
122 addargs(&args, "-v");
123 if (verbose > 1)
124 addargs(&args, "-v");
125 if (verbose > 0)
126 addargs(&args, "-v");
127 if (sess->opts->one_file_system > 1)
128 addargs(&args, "-x");
129 if (sess->opts->one_file_system > 0)
130 addargs(&args, "-x");
131 if (sess->opts->specials && !sess->opts->devices)
132 addargs(&args, "--specials");
133 if (!sess->opts->specials && sess->opts->devices)
134 /* --devices is sent as -D --no-specials */
135 addargs(&args, "--no-specials");
136 if (sess->opts->max_size >= 0)
137 addargs(&args, "--max-size=%lld", sess->opts->max_size);
138 if (sess->opts->min_size >= 0)
139 addargs(&args, "--min-size=%lld", sess->opts->min_size);
140
141 /* extra options for the receiver (local is sender) */
142 if (f->mode == FARGS_SENDER) {
143 if (sess->opts->ignore_dir_times)
144 addargs(&args, "-O");
145 if (sess->opts->ignore_link_times)
146 addargs(&args, "-J");
147 if (sess->opts->size_only)
148 addargs(&args, "--size-only");
149
150 /* only add --compare-dest, etc if this is the sender */
151 if (sess->opts->alt_base_mode != 0) {
152 for (j = 0; j < MAX_BASEDIR20; j++) {
153 if (sess->opts->basedir[j] == NULL((void *)0))
154 break;
155 addargs(&args, "%s=%s",
156 alt_base_mode(sess->opts->alt_base_mode),
157 sess->opts->basedir[j]);
158 }
159 }
160 }
161
162 /* Terminate with a full-stop for reasons unknown. */
163
164 addargs(&args, ".");
165
166 if (f->mode == FARGS_RECEIVER) {
167 for (j = 0; j < f->sourcesz; j++)
168 addargs(&args, "%s", f->sources[j]);
169 } else
170 addargs(&args, "%s", f->sink);
171
172 return args.list;
173}