Skip to content

Commit

Permalink
bpf: Acquire map uref in .init_seq_private for sock{map,hash} iterator
Browse files Browse the repository at this point in the history
sock_map_iter_attach_target() acquires a map uref, and the uref may be
released before or in the middle of iterating map elements. For example,
the uref could be released in sock_map_iter_detach_target() as part of
bpf_link_release(), or could be released in bpf_map_put_with_uref() as
part of bpf_map_release().

Fixing it by acquiring an extra map uref in .init_seq_private and
releasing it in .fini_seq_private.

Fixes: 0365351 ("net: Allow iterating sockmap and sockhash")
Signed-off-by: Hou Tao <[email protected]>
Acked-by: Yonghong Song <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Alexei Starovoitov <[email protected]>
  • Loading branch information
Hou Tao authored and Alexei Starovoitov committed Aug 10, 2022
1 parent 3c5f6e6 commit f0d2b27
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion net/core/sock_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -783,13 +783,22 @@ static int sock_map_init_seq_private(void *priv_data,
{
struct sock_map_seq_info *info = priv_data;

bpf_map_inc_with_uref(aux->map);
info->map = aux->map;
return 0;
}

static void sock_map_fini_seq_private(void *priv_data)
{
struct sock_map_seq_info *info = priv_data;

bpf_map_put_with_uref(info->map);
}

static const struct bpf_iter_seq_info sock_map_iter_seq_info = {
.seq_ops = &sock_map_seq_ops,
.init_seq_private = sock_map_init_seq_private,
.fini_seq_private = sock_map_fini_seq_private,
.seq_priv_size = sizeof(struct sock_map_seq_info),
};

Expand Down Expand Up @@ -1369,18 +1378,27 @@ static const struct seq_operations sock_hash_seq_ops = {
};

static int sock_hash_init_seq_private(void *priv_data,
struct bpf_iter_aux_info *aux)
struct bpf_iter_aux_info *aux)
{
struct sock_hash_seq_info *info = priv_data;

bpf_map_inc_with_uref(aux->map);
info->map = aux->map;
info->htab = container_of(aux->map, struct bpf_shtab, map);
return 0;
}

static void sock_hash_fini_seq_private(void *priv_data)
{
struct sock_hash_seq_info *info = priv_data;

bpf_map_put_with_uref(info->map);
}

static const struct bpf_iter_seq_info sock_hash_iter_seq_info = {
.seq_ops = &sock_hash_seq_ops,
.init_seq_private = sock_hash_init_seq_private,
.fini_seq_private = sock_hash_fini_seq_private,
.seq_priv_size = sizeof(struct sock_hash_seq_info),
};

Expand Down

0 comments on commit f0d2b27

Please sign in to comment.