https://github.com/torvalds/linux
Revision 573b3aa6940661dc50c383213d428c27df78be7c authored by Yonghong Song on 30 July 2018, 15:49:03 UTC, committed by Daniel Borkmann on 30 July 2018, 22:37:09 UTC
I hit the following problem when I tried to use bpftool to dump a percpu array. $ sudo ./bpftool map show 61: percpu_array name stub flags 0x0 key 4B value 4B max_entries 1 memlock 4096B ... $ sudo ./bpftool map dump id 61 bpftool: malloc.c:2406: sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || \ ((unsigned long) (old_size) >= MINSIZE && \ prev_inuse (old_top) && \ ((unsigned long) old_end & (pagesize - 1)) == 0)' failed. Aborted Further debugging revealed that this is due to miscommunication between bpftool and kernel. For example, for the above percpu_array with value size of 4B. The map info returned to user space has value size of 4B. In bpftool, the values array for lookup is allocated like: info->value_size * get_possible_cpus() = 4 * get_possible_cpus() In kernel (kernel/bpf/syscall.c), the values array size is rounded up to multiple of 8. round_up(map->value_size, 8) * num_possible_cpus() = 8 * num_possible_cpus() So when kernel copies the values to user buffer, the kernel will overwrite beyond user buffer boundary. This patch fixed the issue by allocating and stepping through percpu map value array properly in bpftool. Fixes: 71bb428fe2c19 ("tools: bpf: add bpftool") Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 61f4b23
Tip revision: 573b3aa6940661dc50c383213d428c27df78be7c authored by Yonghong Song on 30 July 2018, 15:49:03 UTC
tools/bpftool: fix a percpu_array map dump problem
tools/bpftool: fix a percpu_array map dump problem
Tip revision: 573b3aa
apei.h
/* SPDX-License-Identifier: GPL-2.0 */
/*
* apei.h - ACPI Platform Error Interface
*/
#ifndef ACPI_APEI_H
#define ACPI_APEI_H
#include <linux/acpi.h>
#include <linux/cper.h>
#include <asm/ioctls.h>
#define APEI_ERST_INVALID_RECORD_ID 0xffffffffffffffffULL
#define APEI_ERST_CLEAR_RECORD _IOW('E', 1, u64)
#define APEI_ERST_GET_RECORD_COUNT _IOR('E', 2, u32)
#ifdef __KERNEL__
enum hest_status {
HEST_ENABLED,
HEST_DISABLED,
HEST_NOT_FOUND,
};
extern int hest_disable;
extern int erst_disable;
#ifdef CONFIG_ACPI_APEI_GHES
extern bool ghes_disable;
#else
#define ghes_disable 1
#endif
#ifdef CONFIG_ACPI_APEI
void __init acpi_hest_init(void);
#else
static inline void acpi_hest_init(void) { return; }
#endif
typedef int (*apei_hest_func_t)(struct acpi_hest_header *hest_hdr, void *data);
int apei_hest_parse(apei_hest_func_t func, void *data);
int erst_write(const struct cper_record_header *record);
ssize_t erst_get_record_count(void);
int erst_get_record_id_begin(int *pos);
int erst_get_record_id_next(int *pos, u64 *record_id);
void erst_get_record_id_end(void);
ssize_t erst_read(u64 record_id, struct cper_record_header *record,
size_t buflen);
int erst_clear(u64 record_id);
int arch_apei_enable_cmcff(struct acpi_hest_header *hest_hdr, void *data);
void arch_apei_report_mem_error(int sev, struct cper_sec_mem_err *mem_err);
#endif
#endif
Computing file changes ...