Skip to content

Commit

Permalink
{f, m}_bpf: check map attributes when fetching as pinned
Browse files Browse the repository at this point in the history
Make use of the new show_fdinfo() facility and verify that when a
pinned map is being fetched that its basic attributes are the same
as the map we declared from the ELF file. I.e. when placed into the
globalns, collisions could occur. In such a case warn the user and
bail out.

Signed-off-by: Daniel Borkmann <[email protected]>
Acked-by: Alexei Starovoitov <[email protected]>
  • Loading branch information
borkmann authored and Stephen Hemminger committed Nov 29, 2015
1 parent 910b543 commit 9e607f2
Showing 1 changed file with 53 additions and 0 deletions.
53 changes: 53 additions & 0 deletions tc/tc_bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,52 @@ void bpf_print_ops(FILE *f, struct rtattr *bpf_ops, __u16 len)
ops[i].jf, ops[i].k);
}

static int bpf_map_selfcheck_pinned(int fd, const struct bpf_elf_map *map)
{
char file[PATH_MAX], buff[4096];
struct bpf_elf_map tmp, zero;
unsigned int val;
FILE *fp;

snprintf(file, sizeof(file), "/proc/%d/fdinfo/%d", getpid(), fd);

fp = fopen(file, "r");
if (!fp) {
fprintf(stderr, "No procfs support?!\n");
return -EIO;
}

memset(&tmp, 0, sizeof(tmp));
while (fgets(buff, sizeof(buff), fp)) {
if (sscanf(buff, "map_type:\t%u", &val) == 1)
tmp.type = val;
else if (sscanf(buff, "key_size:\t%u", &val) == 1)
tmp.size_key = val;
else if (sscanf(buff, "value_size:\t%u", &val) == 1)
tmp.size_value = val;
else if (sscanf(buff, "max_entries:\t%u", &val) == 1)
tmp.max_elem = val;
}

fclose(fp);

if (!memcmp(&tmp, map, offsetof(struct bpf_elf_map, id))) {
return 0;
} else {
memset(&zero, 0, sizeof(zero));
/* If kernel doesn't have eBPF-related fdinfo, we cannot do much,
* so just accept it. We know we do have an eBPF fd and in this
* case, everything is 0. It is guaranteed that no such map exists
* since map type of 0 is unloadable BPF_MAP_TYPE_UNSPEC.
*/
if (!memcmp(&tmp, &zero, offsetof(struct bpf_elf_map, id)))
return 0;

fprintf(stderr, "Map specs from pinned file differ!\n");
return -EINVAL;
}
}

static int bpf_valid_mntpt(const char *mnt, unsigned long magic)
{
struct statfs st_fs;
Expand Down Expand Up @@ -816,6 +862,13 @@ static int bpf_map_attach(const char *name, const struct bpf_elf_map *map,

fd = bpf_probe_pinned(name, map->pinning);
if (fd > 0) {
ret = bpf_map_selfcheck_pinned(fd, map);
if (ret < 0) {
close(fd);
fprintf(stderr, "Map \'%s\' self-check failed!\n",
name);
return ret;
}
if (verbose)
fprintf(stderr, "Map \'%s\' loaded as pinned!\n",
name);
Expand Down

0 comments on commit 9e607f2

Please sign in to comment.