File: | build-scan/../src/core/ip-address-access.c |
Warning: | line 185, column 42 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
14 | int 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); | |||
| ||||
31 | ||||
32 | if (isempty(rvalue)) { | |||
33 | *list = ip_address_access_free_all(*list); | |||
34 | return 0; | |||
35 | } | |||
36 | ||||
37 | p = rvalue; | |||
38 | ||||
39 | for (;;) { | |||
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) | |||
45 | break; | |||
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); | |||
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 | ||||
155 | IPAddressAccessItem* 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 | ||||
168 | IPAddressAccessItem* 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)) { | |||
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) { | |||
181 | ||||
182 | if (a
| |||
183 | continue; | |||
184 | ||||
185 | if (a->family != b->family) | |||
| ||||
186 | continue; | |||
187 | ||||
188 | if (b->prefixlen > a->prefixlen) | |||
189 | continue; | |||
190 | ||||
191 | r = in_addr_prefix_covers(b->family, | |||
192 | &b->address, | |||
193 | b->prefixlen, | |||
194 | &a->address); | |||
195 | if (r > 0) { | |||
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); | |||
198 | free(a); | |||
199 | break; | |||
200 | } | |||
201 | } | |||
202 | } | |||
203 | ||||
204 | return first; | |||
205 | } |