| 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 | } |