Bug Summary

File:build-scan/../src/core/ip-address-access.c
Warning:line 204, column 9
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ip-address-access.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 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/core/libcore.a.p -I src/core -I ../src/core -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -I /usr/include/libmount -I /usr/include/blkid -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/core/ip-address-access.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <stdio.h>
4#include <stdlib.h>
5
6#include "alloc-util.h"
7#include "bpf-firewall.h"
8#include "extract-word.h"
9#include "hostname-util.h"
10#include "ip-address-access.h"
11#include "parse-util.h"
12#include "string-util.h"
13
14int config_parse_ip_address_access(
15 const char *unit,
16 const char *filename,
17 unsigned line,
18 const char *section,
19 unsigned section_line,
20 const char *lvalue,
21 int ltype,
22 const char *rvalue,
23 void *data,
24 void *userdata) {
25
26 IPAddressAccessItem **list = data;
27 const char *p;
28 int r;
29
30 assert(list)do { if ((__builtin_expect(!!(!(list)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("list"), "../src/core/ip-address-access.c"
, 30, __PRETTY_FUNCTION__); } while (0)
;
1
Assuming 'list' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
31
32 if (isempty(rvalue)) {
4
Taking false branch
33 *list = ip_address_access_free_all(*list);
34 return 0;
35 }
36
37 p = rvalue;
38
39 for (;;) {
5
Loop condition is true. Entering loop body
40 _cleanup_free___attribute__((cleanup(freep))) IPAddressAccessItem *a = NULL((void*)0);
41 _cleanup_free___attribute__((cleanup(freep))) char *word = NULL((void*)0);
42
43 r = extract_first_word(&p, &word, NULL((void*)0), 0);
44 if (r == 0)
6
Assuming 'r' is equal to 0
7
Taking true branch
45 break;
8
Execution continues on line 135
46 if (r == -ENOMEM12)
47 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/ip-address-access.c"
, 47, __func__)
;
48 if (r < 0) {
49 log_syntax(unit, LOG_WARNING, filename, line, r, "Invalid syntax, ignoring: %s", rvalue)({ int _level = (4), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/core/ip-address-access.c", 49, __func__
, "Invalid syntax, ignoring: %s", rvalue) : -abs(_e); })
;
50 break;
51 }
52
53 a = new0(IPAddressAccessItem, 1)((IPAddressAccessItem*) calloc((1), sizeof(IPAddressAccessItem
)))
;
54 if (!a)
55 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/ip-address-access.c"
, 55, __func__)
;
56
57 if (streq(word, "any")(strcmp((word),("any")) == 0)) {
58 /* "any" is a shortcut for 0.0.0.0/0 and ::/0 */
59
60 a->family = AF_INET2;
61 LIST_APPEND(items, *list, a)do { typeof(*(*list)) *_tail; do { typeof(*(*list)) *_item = (
*list); if (!_item) (_tail) = ((void*)0); else { while (_item
->items_next) _item = _item->items_next; (_tail) = _item
; } } while (0); do { typeof(*(*list)) **_head = &(*list)
, *_a = (_tail), *_b = (a); do { if ((__builtin_expect(!!(!(_b
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_b"), "../src/core/ip-address-access.c"
, 61, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b->
items_next = *_head)) _b->items_next->items_prev = _b; _b
->items_prev = ((void*)0); *_head = _b; } else { if ((_b->
items_next = _a->items_next)) _b->items_next->items_prev
= _b; _b->items_prev = _a; _a->items_next = _b; } } while
(0); } while (0)
;
62
63 a = new0(IPAddressAccessItem, 1)((IPAddressAccessItem*) calloc((1), sizeof(IPAddressAccessItem
)))
;
64 if (!a)
65 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/ip-address-access.c"
, 65, __func__)
;
66
67 a->family = AF_INET610;
68
69 } else if (is_localhost(word)) {
70 /* "localhost" is a shortcut for 127.0.0.0/8 and ::1/128 */
71
72 a->family = AF_INET2;
73 a->address.in.s_addr = htobe32(0x7f000000)__bswap_32 (0x7f000000);
74 a->prefixlen = 8;
75 LIST_APPEND(items, *list, a)do { typeof(*(*list)) *_tail; do { typeof(*(*list)) *_item = (
*list); if (!_item) (_tail) = ((void*)0); else { while (_item
->items_next) _item = _item->items_next; (_tail) = _item
; } } while (0); do { typeof(*(*list)) **_head = &(*list)
, *_a = (_tail), *_b = (a); do { if ((__builtin_expect(!!(!(_b
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_b"), "../src/core/ip-address-access.c"
, 75, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b->
items_next = *_head)) _b->items_next->items_prev = _b; _b
->items_prev = ((void*)0); *_head = _b; } else { if ((_b->
items_next = _a->items_next)) _b->items_next->items_prev
= _b; _b->items_prev = _a; _a->items_next = _b; } } while
(0); } while (0)
;
76
77 a = new0(IPAddressAccessItem, 1)((IPAddressAccessItem*) calloc((1), sizeof(IPAddressAccessItem
)))
;
78 if (!a)
79 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/ip-address-access.c"
, 79, __func__)
;
80
81 a->family = AF_INET610;
82 a->address.in6 = (struct in6_addr) IN6ADDR_LOOPBACK_INIT{ { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } };
83 a->prefixlen = 128;
84
85 } else if (streq(word, "link-local")(strcmp((word),("link-local")) == 0)) {
86
87 /* "link-local" is a shortcut for 169.254.0.0/16 and fe80::/64 */
88
89 a->family = AF_INET2;
90 a->address.in.s_addr = htobe32((UINT32_C(169) << 24 | UINT32_C(254) << 16))__bswap_32 ((169U << 24 | 254U << 16));
91 a->prefixlen = 16;
92 LIST_APPEND(items, *list, a)do { typeof(*(*list)) *_tail; do { typeof(*(*list)) *_item = (
*list); if (!_item) (_tail) = ((void*)0); else { while (_item
->items_next) _item = _item->items_next; (_tail) = _item
; } } while (0); do { typeof(*(*list)) **_head = &(*list)
, *_a = (_tail), *_b = (a); do { if ((__builtin_expect(!!(!(_b
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_b"), "../src/core/ip-address-access.c"
, 92, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b->
items_next = *_head)) _b->items_next->items_prev = _b; _b
->items_prev = ((void*)0); *_head = _b; } else { if ((_b->
items_next = _a->items_next)) _b->items_next->items_prev
= _b; _b->items_prev = _a; _a->items_next = _b; } } while
(0); } while (0)
;
93
94 a = new0(IPAddressAccessItem, 1)((IPAddressAccessItem*) calloc((1), sizeof(IPAddressAccessItem
)))
;
95 if (!a)
96 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/ip-address-access.c"
, 96, __func__)
;
97
98 a->family = AF_INET610;
99 a->address.in6 = (struct in6_addr) {
100 .s6_addr32__in6_u.__u6_addr32[0] = htobe32(0xfe800000)__bswap_32 (0xfe800000)
101 };
102 a->prefixlen = 64;
103
104 } else if (streq(word, "multicast")(strcmp((word),("multicast")) == 0)) {
105
106 /* "multicast" is a shortcut for 224.0.0.0/4 and ff00::/8 */
107
108 a->family = AF_INET2;
109 a->address.in.s_addr = htobe32((UINT32_C(224) << 24))__bswap_32 ((224U << 24));
110 a->prefixlen = 4;
111 LIST_APPEND(items, *list, a)do { typeof(*(*list)) *_tail; do { typeof(*(*list)) *_item = (
*list); if (!_item) (_tail) = ((void*)0); else { while (_item
->items_next) _item = _item->items_next; (_tail) = _item
; } } while (0); do { typeof(*(*list)) **_head = &(*list)
, *_a = (_tail), *_b = (a); do { if ((__builtin_expect(!!(!(_b
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_b"), "../src/core/ip-address-access.c"
, 111, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b->
items_next = *_head)) _b->items_next->items_prev = _b; _b
->items_prev = ((void*)0); *_head = _b; } else { if ((_b->
items_next = _a->items_next)) _b->items_next->items_prev
= _b; _b->items_prev = _a; _a->items_next = _b; } } while
(0); } while (0)
;
112
113 a = new0(IPAddressAccessItem, 1)((IPAddressAccessItem*) calloc((1), sizeof(IPAddressAccessItem
)))
;
114 if (!a)
115 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/ip-address-access.c"
, 115, __func__)
;
116
117 a->family = AF_INET610;
118 a->address.in6 = (struct in6_addr) {
119 .s6_addr32__in6_u.__u6_addr32[0] = htobe32(0xff000000)__bswap_32 (0xff000000)
120 };
121 a->prefixlen = 8;
122
123 } else {
124 r = in_addr_prefix_from_string_auto(word, &a->family, &a->address, &a->prefixlen);
125 if (r < 0) {
126 log_syntax(unit, LOG_WARNING, filename, line, r, "Address prefix is invalid, ignoring assignment: %s", word)({ int _level = (4), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD
) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level
, filename, line, _e, "../src/core/ip-address-access.c", 126,
__func__, "Address prefix is invalid, ignoring assignment: %s"
, word) : -abs(_e); })
;
127 return 0;
128 }
129 }
130
131 LIST_APPEND(items, *list, a)do { typeof(*(*list)) *_tail; do { typeof(*(*list)) *_item = (
*list); if (!_item) (_tail) = ((void*)0); else { while (_item
->items_next) _item = _item->items_next; (_tail) = _item
; } } while (0); do { typeof(*(*list)) **_head = &(*list)
, *_a = (_tail), *_b = (a); do { if ((__builtin_expect(!!(!(_b
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_b"), "../src/core/ip-address-access.c"
, 131, __PRETTY_FUNCTION__); } while (0); if (!_a) { if ((_b->
items_next = *_head)) _b->items_next->items_prev = _b; _b
->items_prev = ((void*)0); *_head = _b; } else { if ((_b->
items_next = _a->items_next)) _b->items_next->items_prev
= _b; _b->items_prev = _a; _a->items_next = _b; } } while
(0); } while (0)
;
132 a = NULL((void*)0);
133 }
134
135 *list = ip_address_access_reduce(*list);
9
Calling 'ip_address_access_reduce'
136
137 if (*list) {
138 r = bpf_firewall_supported();
139 if (r < 0)
140 return r;
141 if (r == BPF_FIREWALL_UNSUPPORTED) {
142 static bool_Bool warned = false0;
143
144 log_full(warned ? LOG_DEBUG : LOG_WARNING,({ int _level = (((warned ? 7 : 4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/ip-address-access.c", 146, __func__, "File %s:%u configures an IP firewall (%s=%s), but the local system does not support BPF/cgroup based firewalling.\n"
"Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)"
, filename, line, lvalue, rvalue) : -abs(_e); })
145 "File %s:%u configures an IP firewall (%s=%s), but the local system does not support BPF/cgroup based firewalling.\n"({ int _level = (((warned ? 7 : 4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/ip-address-access.c", 146, __func__, "File %s:%u configures an IP firewall (%s=%s), but the local system does not support BPF/cgroup based firewalling.\n"
"Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)"
, filename, line, lvalue, rvalue) : -abs(_e); })
146 "Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)", filename, line, lvalue, rvalue)({ int _level = (((warned ? 7 : 4))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/ip-address-access.c", 146, __func__, "File %s:%u configures an IP firewall (%s=%s), but the local system does not support BPF/cgroup based firewalling.\n"
"Proceeding WITHOUT firewalling in effect! (This warning is only shown for the first loaded unit using IP firewalling.)"
, filename, line, lvalue, rvalue) : -abs(_e); })
;
147
148 warned = true1;
149 }
150 }
151
152 return 0;
153}
154
155IPAddressAccessItem* ip_address_access_free_all(IPAddressAccessItem *first) {
156 IPAddressAccessItem *next, *p = first;
157
158 while (p) {
159 next = p->items_next;
160 free(p);
161
162 p = next;
163 }
164
165 return NULL((void*)0);
166}
167
168IPAddressAccessItem* ip_address_access_reduce(IPAddressAccessItem *first) {
169 IPAddressAccessItem *a, *b, *tmp;
170 int r;
171
172 /* Drops all entries from the list that are covered by another entry in full, thus removing all redundant
173 * entries. */
174
175 LIST_FOREACH_SAFE(items, a, tmp, first)for ((a) = (first); (a) && (((tmp) = (a)->items_next
), 1); (a) = (tmp))
{
10
Assuming 'a' is non-null
11
Loop condition is true. Entering loop body
32
Assuming 'a' is null
176
177 /* Drop irrelevant bits */
178 (void) in_addr_mask(a->family, &a->address, a->prefixlen);
179
180 LIST_FOREACH(items, b, first)for ((b) = (first); (b); (b) = (b)->items_next) {
12
Loop condition is true. Entering loop body
15
Loop condition is true. Entering loop body
181
182 if (a
12.1
'a' is equal to 'b'
== b
)
13
Taking true branch
16
Assuming 'a' is not equal to 'b'
17
Taking false branch
183 continue;
14
Execution continues on line 180
184
185 if (a->family != b->family)
18
Assuming 'a->family' is equal to 'b->family'
19
Taking false branch
186 continue;
187
188 if (b->prefixlen > a->prefixlen)
20
Assuming 'b->prefixlen' is <= 'a->prefixlen'
21
Taking false branch
189 continue;
190
191 r = in_addr_prefix_covers(b->family,
192 &b->address,
193 b->prefixlen,
194 &a->address);
195 if (r > 0) {
22
Assuming 'r' is > 0
23
Taking true branch
196 /* b covers a fully, then let's drop a */
197 LIST_REMOVE(items, first, a)do { typeof(*(first)) **_head = &(first), *_item = (a); do
{ if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/core/ip-address-access.c"
, 197, __PRETTY_FUNCTION__); } while (0); if (_item->items_next
) _item->items_next->items_prev = _item->items_prev;
if (_item->items_prev) _item->items_prev->items_next
= _item->items_next; else { do { if ((__builtin_expect(!!
(!(*_head == _item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD
, ("*_head == _item"), "../src/core/ip-address-access.c", 197
, __PRETTY_FUNCTION__); } while (0); *_head = _item->items_next
; } _item->items_next = _item->items_prev = ((void*)0);
} while (0)
;
24
Taking false branch
25
Loop condition is false. Exiting loop
26
Taking true branch
27
Assuming field 'items_prev' is non-null
28
Taking true branch
29
Loop condition is false. Exiting loop
198 free(a);
30
Memory is released
199 break;
31
Execution continues on line 175
200 }
201 }
202 }
203
204 return first;
33
Use of memory after it is freed
205}