bpf: check for owner_prog_type and notify users when differ
Kernel commit 21116b7068b9 ("bpf: add owner_prog_type and accounted mem
to array map's fdinfo") added support for telling the owner prog type in
case of prog arrays. Give a notification to the user when they differ,
and the program eventually fails to load.
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
0f74d0f3a9
commit
fb24802b9c
18
lib/bpf.c
18
lib/bpf.c
|
|
@ -273,11 +273,11 @@ static void bpf_map_pin_report(const struct bpf_elf_map *pin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map,
|
static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map,
|
||||||
int length)
|
int length, enum bpf_prog_type type)
|
||||||
{
|
{
|
||||||
char file[PATH_MAX], buff[4096];
|
char file[PATH_MAX], buff[4096];
|
||||||
struct bpf_elf_map tmp = {}, zero = {};
|
struct bpf_elf_map tmp = {}, zero = {};
|
||||||
unsigned int val;
|
unsigned int val, owner_type = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
snprintf(file, sizeof(file), "/proc/%d/fdinfo/%d", getpid(), fd);
|
snprintf(file, sizeof(file), "/proc/%d/fdinfo/%d", getpid(), fd);
|
||||||
|
|
@ -299,10 +299,19 @@ static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map,
|
||||||
tmp.max_elem = val;
|
tmp.max_elem = val;
|
||||||
else if (sscanf(buff, "map_flags:\t%i", &val) == 1)
|
else if (sscanf(buff, "map_flags:\t%i", &val) == 1)
|
||||||
tmp.flags = val;
|
tmp.flags = val;
|
||||||
|
else if (sscanf(buff, "owner_prog_type:\t%i", &val) == 1)
|
||||||
|
owner_type = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
/* The decision to reject this is on kernel side eventually, but
|
||||||
|
* at least give the user a chance to know what's wrong.
|
||||||
|
*/
|
||||||
|
if (owner_type && owner_type != type)
|
||||||
|
fprintf(stderr, "Program array map owner types differ: %u (obj) != %u (pin)\n",
|
||||||
|
type, owner_type);
|
||||||
|
|
||||||
if (!memcmp(&tmp, map, length)) {
|
if (!memcmp(&tmp, map, length)) {
|
||||||
return 0;
|
return 0;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -818,7 +827,8 @@ int bpf_graft_map(const char *map_path, uint32_t *key, int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = bpf_map_selfcheck_pinned(map_fd, &test,
|
ret = bpf_map_selfcheck_pinned(map_fd, &test,
|
||||||
offsetof(struct bpf_elf_map, max_elem));
|
offsetof(struct bpf_elf_map, max_elem),
|
||||||
|
type);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
fprintf(stderr, "Map \'%s\' self-check failed!\n", map_path);
|
fprintf(stderr, "Map \'%s\' self-check failed!\n", map_path);
|
||||||
goto out_map;
|
goto out_map;
|
||||||
|
|
@ -1303,7 +1313,7 @@ static int bpf_map_attach(const char *name, const struct bpf_elf_map *map,
|
||||||
if (fd > 0) {
|
if (fd > 0) {
|
||||||
ret = bpf_map_selfcheck_pinned(fd, map,
|
ret = bpf_map_selfcheck_pinned(fd, map,
|
||||||
offsetof(struct bpf_elf_map,
|
offsetof(struct bpf_elf_map,
|
||||||
id));
|
id), ctx->type);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
close(fd);
|
close(fd);
|
||||||
fprintf(stderr, "Map \'%s\' self-check failed!\n",
|
fprintf(stderr, "Map \'%s\' self-check failed!\n",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue