bpf_map_init_from_attr(&insn_array->map, attr);
+ /* BPF programs aren't allowed to write to the map */
+ insn_array->map.map_flags |= BPF_F_RDONLY_PROG;
+
return &insn_array->map;
}
verbose(env, "R%d leaks addr into map\n", value_regno);
return -EACCES;
}
- if (t == BPF_WRITE && insn_array) {
- verbose(env, "writes into insn_array not allowed\n");
- return -EACCES;
- }
-
err = check_map_access_type(env, regno, off, size, t);
if (err)
return err;
} else if (t == BPF_READ && value_regno >= 0) {
struct bpf_map *map = reg->map_ptr;
- /* if map is read-only, track its contents as scalars */
+ /*
+ * If map is read-only, track its contents as scalars,
+ * unless it is an insn array (see the special case below)
+ */
if (tnum_is_const(reg->var_off) &&
bpf_map_is_rdonly(map) &&
- map->ops->map_direct_value_addr) {
+ map->ops->map_direct_value_addr &&
+ map->map_type != BPF_MAP_TYPE_INSN_ARRAY) {
int map_off = off + reg->var_off.value;
u64 val = 0;