Skip to content

Commit 2bea33f

Browse files
committed
Merge branch 'bpf-add-percpu-map-value-size-check'
Tao Chen says: ==================== bpf: Add percpu map value size check Check percpu map value size first and add the test case in selftest. Change list: - v2 -> v3: - use bpf_map_create API and mv test case in map_percpu_stats.c - v1 -> v2: - round up map value size with 8 bytes in patch 1 - add selftest case in patch 2 ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Andrii Nakryiko <[email protected]>
2 parents 300a90b + 7eab3a5 commit 2bea33f

File tree

3 files changed

+24
-0
lines changed

3 files changed

+24
-0
lines changed

kernel/bpf/arraymap.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,9 @@ int array_map_alloc_check(union bpf_attr *attr)
7373
/* avoid overflow on round_up(map->value_size) */
7474
if (attr->value_size > INT_MAX)
7575
return -E2BIG;
76+
/* percpu map value size is bound by PCPU_MIN_UNIT_SIZE */
77+
if (percpu && round_up(attr->value_size, 8) > PCPU_MIN_UNIT_SIZE)
78+
return -E2BIG;
7679

7780
return 0;
7881
}

kernel/bpf/hashtab.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,9 @@ static int htab_map_alloc_check(union bpf_attr *attr)
462462
* kmalloc-able later in htab_map_update_elem()
463463
*/
464464
return -E2BIG;
465+
/* percpu map value size is bound by PCPU_MIN_UNIT_SIZE */
466+
if (percpu && round_up(attr->value_size, 8) > PCPU_MIN_UNIT_SIZE)
467+
return -E2BIG;
465468

466469
return 0;
467470
}

tools/testing/selftests/bpf/map_tests/map_percpu_stats.c

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define MAX_ENTRIES_HASH_OF_MAPS 64
1818
#define N_THREADS 8
1919
#define MAX_MAP_KEY_SIZE 4
20+
#define PCPU_MIN_UNIT_SIZE 32768
2021

2122
static void map_info(int map_fd, struct bpf_map_info *info)
2223
{
@@ -456,6 +457,22 @@ static void map_percpu_stats_hash_of_maps(void)
456457
printf("test_%s:PASS\n", __func__);
457458
}
458459

460+
static void map_percpu_stats_map_value_size(void)
461+
{
462+
int fd;
463+
int value_sz = PCPU_MIN_UNIT_SIZE + 1;
464+
struct bpf_map_create_opts opts = { .sz = sizeof(opts) };
465+
enum bpf_map_type map_types[] = { BPF_MAP_TYPE_PERCPU_ARRAY,
466+
BPF_MAP_TYPE_PERCPU_HASH,
467+
BPF_MAP_TYPE_LRU_PERCPU_HASH };
468+
for (int i = 0; i < ARRAY_SIZE(map_types); i++) {
469+
fd = bpf_map_create(map_types[i], NULL, sizeof(__u32), value_sz, 1, &opts);
470+
CHECK(fd < 0 && errno != E2BIG, "percpu map value size",
471+
"error: %s\n", strerror(errno));
472+
}
473+
printf("test_%s:PASS\n", __func__);
474+
}
475+
459476
void test_map_percpu_stats(void)
460477
{
461478
map_percpu_stats_hash();
@@ -467,4 +484,5 @@ void test_map_percpu_stats(void)
467484
map_percpu_stats_percpu_lru_hash();
468485
map_percpu_stats_percpu_lru_hash_no_common();
469486
map_percpu_stats_hash_of_maps();
487+
map_percpu_stats_map_value_size();
470488
}

0 commit comments

Comments
 (0)