On 01/23/2017 05:39 PM, Daniel Borkmann wrote: > On 01/21/2017 05:26 PM, Daniel Mack wrote: > [...] >> +/* Called from syscall or from eBPF program */ >> +static int trie_update_elem(struct bpf_map *map, >> + void *_key, void *value, u64 flags) >> +{ >> + struct lpm_trie *trie = container_of(map, struct lpm_trie, map); >> + struct lpm_trie_node *node, *im_node, *new_node = NULL; > > im_node is uninitialized here ... > >> + struct lpm_trie_node __rcu **slot; >> + struct bpf_lpm_trie_key *key = _key; >> + unsigned long irq_flags; >> + unsigned int next_bit; >> + size_t matchlen = 0; >> + int ret = 0; >> + >> + if (unlikely(flags > BPF_EXIST)) >> + return -EINVAL; >> + >> + if (key->prefixlen > trie->max_prefixlen) >> + return -EINVAL; >> + >> + raw_spin_lock_irqsave(&trie->lock, irq_flags); >> + >> + /* Allocate and fill a new node */ >> + >> + if (trie->n_entries == trie->map.max_entries) { >> + ret = -ENOSPC; >> + goto out; > > ... and here we go to out path with ret as non-zero ... > >> + } >> + >> + new_node = lpm_trie_node_alloc(trie, value); >> + if (!new_node) { >> + ret = -ENOMEM; >> + goto out; >> + } > [...] >> + >> +out: >> + if (ret) { >> + if (new_node) >> + trie->n_entries--; >> + >> + kfree(new_node); >> + kfree(im_node); > > ... which does kfree() in im_node here.
Oops. Nice catch! gcc was too stupid to recognize that :) Thanks, I'll repost a v5 with Alexei's Acked-by later today. Daniel