mirror of
https://github.com/systemd/systemd.git
synced 2024-10-31 16:21:26 +03:00
network: fix memory leak when an netdev was skipped
In general we'd leak anything that was allocated in the first parsing of netdev, e.g. netdev name, host name, etc. Use normal netdev_unref to make sure everything is freed. --- command --- /home/zbyszek/src/systemd/build2/test-network --- stderr --- /etc/systemd/network/wg0.netdev:3: Failed to parse netdev kind, ignoring: wireguard /etc/systemd/network/wg0.netdev:5: Unknown section 'WireGuard'. Ignoring. /etc/systemd/network/wg0.netdev:9: Unknown section 'WireGuardPeer'. Ignoring. NetDev has no Kind configured in /etc/systemd/network/wg0.netdev. Ignoring /etc/systemd/network/br0.network:13: Unknown lvalue 'NetDev' in section 'Network' br0: netdev ready ================================================================= ==11666==ERROR: LeakSanitizer: detected memory leaks Direct leak of 4 byte(s) in 1 object(s) allocated from: #0 0x7f3a314cf238 in __interceptor_strdup (/lib64/libasan.so.4+0x77238) #1 0x7f3a30e71ad1 in free_and_strdup ../src/basic/string-util.c:870 #2 0x7f3a30d34fba in config_parse_ifname ../src/shared/conf-parser.c:981 #3 0x7f3a30d2f5b0 in next_assignment ../src/shared/conf-parser.c:155 #4 0x7f3a30d30303 in parse_line ../src/shared/conf-parser.c:273 #5 0x7f3a30d30dee in config_parse ../src/shared/conf-parser.c:390 #6 0x7f3a30d310a5 in config_parse_many_files ../src/shared/conf-parser.c:428 #7 0x7f3a30d3181c in config_parse_many ../src/shared/conf-parser.c:487 #8 0x55b4200f9b00 in netdev_load_one ../src/network/netdev/netdev.c:634 #9 0x55b4200fb562 in netdev_load ../src/network/netdev/netdev.c:778 #10 0x55b4200c607a in manager_load_config ../src/network/networkd-manager.c:1299 #11 0x55b4200818e0 in test_load_config ../src/network/test-network.c:128 #12 0x55b42008343b in main ../src/network/test-network.c:254 #13 0x7f3a305f8889 in __libc_start_main (/lib64/libc.so.6+0x20889) SUMMARY: AddressSanitizer: 4 byte(s) leaked in 1 allocation(s). -------
This commit is contained in:
parent
af126c9623
commit
281bb5c110
@ -138,7 +138,7 @@ static void netdev_free(NetDev *netdev) {
|
||||
|
||||
netdev_cancel_callbacks(netdev);
|
||||
|
||||
if (netdev->ifname)
|
||||
if (netdev->ifname && netdev->manager)
|
||||
hashmap_remove(netdev->manager->netdevs, netdev->ifname);
|
||||
|
||||
free(netdev->filename);
|
||||
@ -601,8 +601,7 @@ int netdev_join(NetDev *netdev, Link *link, sd_netlink_message_handler_t callbac
|
||||
}
|
||||
|
||||
static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
_cleanup_netdev_unref_ NetDev *netdev = NULL;
|
||||
_cleanup_free_ NetDev *netdev_raw = NULL;
|
||||
_cleanup_netdev_unref_ NetDev *netdev_raw = NULL, *netdev = NULL;
|
||||
_cleanup_fclose_ FILE *file = NULL;
|
||||
const char *dropin_dirname;
|
||||
bool independent = false;
|
||||
@ -628,9 +627,11 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
if (!netdev_raw)
|
||||
return log_oom();
|
||||
|
||||
netdev_raw->n_ref = 1;
|
||||
netdev_raw->kind = _NETDEV_KIND_INVALID;
|
||||
dropin_dirname = strjoina(basename(filename), ".d");
|
||||
netdev_raw->state = _NETDEV_STATE_INVALID;
|
||||
|
||||
dropin_dirname = strjoina(basename(filename), ".d");
|
||||
r = config_parse_many(filename, network_dirs, dropin_dirname,
|
||||
"Match\0NetDev\0",
|
||||
config_item_perf_lookup, network_netdev_gperf_lookup,
|
||||
@ -638,10 +639,6 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = fseek(file, 0, SEEK_SET);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
/* skip out early if configuration does not match the environment */
|
||||
if (net_match_config(NULL, NULL, NULL, NULL, NULL,
|
||||
netdev_raw->match_host, netdev_raw->match_virt,
|
||||
@ -659,15 +656,18 @@ static int netdev_load_one(Manager *manager, const char *filename) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = fseek(file, 0, SEEK_SET);
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
netdev = malloc0(NETDEV_VTABLE(netdev_raw)->object_size);
|
||||
if (!netdev)
|
||||
return log_oom();
|
||||
|
||||
netdev->n_ref = 1;
|
||||
netdev->manager = manager;
|
||||
netdev->state = _NETDEV_STATE_INVALID;
|
||||
netdev->kind = netdev_raw->kind;
|
||||
netdev->ifname = netdev_raw->ifname;
|
||||
netdev->state = _NETDEV_STATE_INVALID;
|
||||
|
||||
if (NETDEV_VTABLE(netdev)->init)
|
||||
NETDEV_VTABLE(netdev)->init(netdev);
|
||||
|
@ -143,7 +143,7 @@ typedef struct NetDevVTable {
|
||||
|
||||
extern const NetDevVTable * const netdev_vtable[_NETDEV_KIND_MAX];
|
||||
|
||||
#define NETDEV_VTABLE(n) netdev_vtable[(n)->kind]
|
||||
#define NETDEV_VTABLE(n) ((n)->kind != _NETDEV_KIND_INVALID ? netdev_vtable[(n)->kind] : NULL)
|
||||
|
||||
/* For casting a netdev into the various netdev kinds */
|
||||
#define DEFINE_NETDEV_CAST(UPPERCASE, MixedCase) \
|
||||
|
Loading…
Reference in New Issue
Block a user