@@ -1628,7 +1628,7 @@ bool bpf_map_equal_kptr_off_tab(const struct bpf_map *map_a, const struct bpf_ma
void bpf_map_free_kptrs(struct bpf_map *map, void *map_value);
struct bpf_map *bpf_map_get(u32 ufd);
-struct bpf_map *bpf_map_get_with_uref(u32 ufd);
+struct bpf_map *bpf_map_get_with_uref(u32 ufd, fmode_t req_modes);
struct bpf_map *__bpf_map_get(struct fd f);
void bpf_map_inc(struct bpf_map *map);
void bpf_map_inc_with_uref(struct bpf_map *map);
@@ -71,7 +71,7 @@ static void *bpf_fd_probe_obj(u32 ufd, enum bpf_type *type)
{
void *raw;
- raw = bpf_map_get_with_uref(ufd);
+ raw = bpf_map_get_with_uref(ufd, 0);
if (!IS_ERR(raw)) {
*type = BPF_TYPE_MAP;
return raw;
@@ -110,7 +110,8 @@ static int bpf_iter_attach_map(struct bpf_prog *prog,
if (!linfo->map.map_fd)
return -EBADF;
- map = bpf_map_get_with_uref(linfo->map.map_fd);
+ map = bpf_map_get_with_uref(linfo->map.map_fd,
+ FMODE_CAN_READ | FMODE_CAN_WRITE);
if (IS_ERR(map))
return PTR_ERR(map);
@@ -1232,7 +1232,7 @@ struct bpf_map *bpf_map_get(u32 ufd)
}
EXPORT_SYMBOL(bpf_map_get);
-struct bpf_map *bpf_map_get_with_uref(u32 ufd)
+struct bpf_map *bpf_map_get_with_uref(u32 ufd, fmode_t req_modes)
{
struct fd f = fdget(ufd);
struct bpf_map *map;
@@ -1241,7 +1241,13 @@ struct bpf_map *bpf_map_get_with_uref(u32 ufd)
if (IS_ERR(map))
return map;
+ if ((map_get_sys_perms(map, f) & req_modes) != req_modes) {
+ map = ERR_PTR(-EPERM);
+ goto out;
+ }
+
bpf_map_inc_with_uref(map);
+out:
fdput(f);
return map;
@@ -897,7 +897,8 @@ static int bpf_iter_attach_map(struct bpf_prog *prog,
if (!linfo->map.map_fd)
return -EBADF;
- map = bpf_map_get_with_uref(linfo->map.map_fd);
+ map = bpf_map_get_with_uref(linfo->map.map_fd,
+ FMODE_CAN_READ | FMODE_CAN_WRITE);
if (IS_ERR(map))
return PTR_ERR(map);
@@ -1636,7 +1636,8 @@ static int sock_map_iter_attach_target(struct bpf_prog *prog,
if (!linfo->map.map_fd)
return -EBADF;
- map = bpf_map_get_with_uref(linfo->map.map_fd);
+ map = bpf_map_get_with_uref(linfo->map.map_fd,
+ FMODE_CAN_READ | FMODE_CAN_WRITE);
if (IS_ERR(map))
return PTR_ERR(map);