aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/bpf/syscall.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r--kernel/bpf/syscall.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index c286e75ec087..bfcde949c7f8 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -255,7 +255,6 @@ static void bpf_map_free_deferred(struct work_struct *work)
255 255
256 bpf_map_uncharge_memlock(map); 256 bpf_map_uncharge_memlock(map);
257 security_bpf_map_free(map); 257 security_bpf_map_free(map);
258 btf_put(map->btf);
259 /* implementation dependent freeing */ 258 /* implementation dependent freeing */
260 map->ops->map_free(map); 259 map->ops->map_free(map);
261} 260}
@@ -276,6 +275,7 @@ static void __bpf_map_put(struct bpf_map *map, bool do_idr_lock)
276 if (atomic_dec_and_test(&map->refcnt)) { 275 if (atomic_dec_and_test(&map->refcnt)) {
277 /* bpf_map_free_id() must be called first */ 276 /* bpf_map_free_id() must be called first */
278 bpf_map_free_id(map, do_idr_lock); 277 bpf_map_free_id(map, do_idr_lock);
278 btf_put(map->btf);
279 INIT_WORK(&map->work, bpf_map_free_deferred); 279 INIT_WORK(&map->work, bpf_map_free_deferred);
280 schedule_work(&map->work); 280 schedule_work(&map->work);
281 } 281 }
@@ -2011,6 +2011,12 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
2011 info.map_flags = map->map_flags; 2011 info.map_flags = map->map_flags;
2012 memcpy(info.name, map->name, sizeof(map->name)); 2012 memcpy(info.name, map->name, sizeof(map->name));
2013 2013
2014 if (map->btf) {
2015 info.btf_id = btf_id(map->btf);
2016 info.btf_key_id = map->btf_key_id;
2017 info.btf_value_id = map->btf_value_id;
2018 }
2019
2014 if (bpf_map_is_dev_bound(map)) { 2020 if (bpf_map_is_dev_bound(map)) {
2015 err = bpf_map_offload_info_fill(&info, map); 2021 err = bpf_map_offload_info_fill(&info, map);
2016 if (err) 2022 if (err)
@@ -2024,6 +2030,21 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
2024 return 0; 2030 return 0;
2025} 2031}
2026 2032
2033static int bpf_btf_get_info_by_fd(struct btf *btf,
2034 const union bpf_attr *attr,
2035 union bpf_attr __user *uattr)
2036{
2037 struct bpf_btf_info __user *uinfo = u64_to_user_ptr(attr->info.info);
2038 u32 info_len = attr->info.info_len;
2039 int err;
2040
2041 err = check_uarg_tail_zero(uinfo, sizeof(*uinfo), info_len);
2042 if (err)
2043 return err;
2044
2045 return btf_get_info_by_fd(btf, attr, uattr);
2046}
2047
2027#define BPF_OBJ_GET_INFO_BY_FD_LAST_FIELD info.info 2048#define BPF_OBJ_GET_INFO_BY_FD_LAST_FIELD info.info
2028 2049
2029static int bpf_obj_get_info_by_fd(const union bpf_attr *attr, 2050static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
@@ -2047,7 +2068,7 @@ static int bpf_obj_get_info_by_fd(const union bpf_attr *attr,
2047 err = bpf_map_get_info_by_fd(f.file->private_data, attr, 2068 err = bpf_map_get_info_by_fd(f.file->private_data, attr,
2048 uattr); 2069 uattr);
2049 else if (f.file->f_op == &btf_fops) 2070 else if (f.file->f_op == &btf_fops)
2050 err = btf_get_info_by_fd(f.file->private_data, attr, uattr); 2071 err = bpf_btf_get_info_by_fd(f.file->private_data, attr, uattr);
2051 else 2072 else
2052 err = -EINVAL; 2073 err = -EINVAL;
2053 2074
@@ -2068,6 +2089,19 @@ static int bpf_btf_load(const union bpf_attr *attr)
2068 return btf_new_fd(attr); 2089 return btf_new_fd(attr);
2069} 2090}
2070 2091
2092#define BPF_BTF_GET_FD_BY_ID_LAST_FIELD btf_id
2093
2094static int bpf_btf_get_fd_by_id(const union bpf_attr *attr)
2095{
2096 if (CHECK_ATTR(BPF_BTF_GET_FD_BY_ID))
2097 return -EINVAL;
2098
2099 if (!capable(CAP_SYS_ADMIN))
2100 return -EPERM;
2101
2102 return btf_get_fd_by_id(attr->btf_id);
2103}
2104
2071SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size) 2105SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
2072{ 2106{
2073 union bpf_attr attr = {}; 2107 union bpf_attr attr = {};
@@ -2151,6 +2185,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
2151 case BPF_BTF_LOAD: 2185 case BPF_BTF_LOAD:
2152 err = bpf_btf_load(&attr); 2186 err = bpf_btf_load(&attr);
2153 break; 2187 break;
2188 case BPF_BTF_GET_FD_BY_ID:
2189 err = bpf_btf_get_fd_by_id(&attr);
2190 break;
2154 default: 2191 default:
2155 err = -EINVAL; 2192 err = -EINVAL;
2156 break; 2193 break;