Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

devmap: Use bpf_map_area_alloc() for allocating hash buckets

Syzkaller discovered that creating a hash of type devmap_hash with a large
number of entries can hit the memory allocator limit for allocating
contiguous memory regions. There's really no reason to use kmalloc_array()
directly in the devmap code, so just switch it to the existing
bpf_map_area_alloc() function that is used elsewhere.

Fixes: 6f9d451ab1a3 ("xdp: Add devmap_hash map type for looking up devices by hashed index")
Reported-by: Xiumei Mu <xmu@redhat.com>
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: John Fastabend <john.fastabend@gmail.com>
Link: https://lore.kernel.org/bpf/20200616142829.114173-1-toke@redhat.com

authored by

Toke Høiland-Jørgensen and committed by
Alexei Starovoitov
99c51064 3ff23516

+6 -4
+6 -4
kernel/bpf/devmap.c
··· 86 86 static DEFINE_SPINLOCK(dev_map_lock); 87 87 static LIST_HEAD(dev_map_list); 88 88 89 - static struct hlist_head *dev_map_create_hash(unsigned int entries) 89 + static struct hlist_head *dev_map_create_hash(unsigned int entries, 90 + int numa_node) 90 91 { 91 92 int i; 92 93 struct hlist_head *hash; 93 94 94 - hash = kmalloc_array(entries, sizeof(*hash), GFP_KERNEL); 95 + hash = bpf_map_area_alloc(entries * sizeof(*hash), numa_node); 95 96 if (hash != NULL) 96 97 for (i = 0; i < entries; i++) 97 98 INIT_HLIST_HEAD(&hash[i]); ··· 146 145 return -EINVAL; 147 146 148 147 if (attr->map_type == BPF_MAP_TYPE_DEVMAP_HASH) { 149 - dtab->dev_index_head = dev_map_create_hash(dtab->n_buckets); 148 + dtab->dev_index_head = dev_map_create_hash(dtab->n_buckets, 149 + dtab->map.numa_node); 150 150 if (!dtab->dev_index_head) 151 151 goto free_charge; 152 152 ··· 234 232 } 235 233 } 236 234 237 - kfree(dtab->dev_index_head); 235 + bpf_map_area_free(dtab->dev_index_head); 238 236 } else { 239 237 for (i = 0; i < dtab->map.max_entries; i++) { 240 238 struct bpf_dtab_netdev *dev;