diff options
Diffstat (limited to 'kernel/bpf/syscall.c')
-rw-r--r-- | kernel/bpf/syscall.c | 24 |
1 files changed, 23 insertions, 1 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 9b87198deea2..31c4092da277 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -252,7 +252,6 @@ static void bpf_map_free_deferred(struct work_struct *work) | |||
252 | 252 | ||
253 | bpf_map_uncharge_memlock(map); | 253 | bpf_map_uncharge_memlock(map); |
254 | security_bpf_map_free(map); | 254 | security_bpf_map_free(map); |
255 | btf_put(map->btf); | ||
256 | /* implementation dependent freeing */ | 255 | /* implementation dependent freeing */ |
257 | map->ops->map_free(map); | 256 | map->ops->map_free(map); |
258 | } | 257 | } |
@@ -273,6 +272,7 @@ static void __bpf_map_put(struct bpf_map *map, bool do_idr_lock) | |||
273 | if (atomic_dec_and_test(&map->refcnt)) { | 272 | if (atomic_dec_and_test(&map->refcnt)) { |
274 | /* bpf_map_free_id() must be called first */ | 273 | /* bpf_map_free_id() must be called first */ |
275 | bpf_map_free_id(map, do_idr_lock); | 274 | bpf_map_free_id(map, do_idr_lock); |
275 | btf_put(map->btf); | ||
276 | INIT_WORK(&map->work, bpf_map_free_deferred); | 276 | INIT_WORK(&map->work, bpf_map_free_deferred); |
277 | schedule_work(&map->work); | 277 | schedule_work(&map->work); |
278 | } | 278 | } |
@@ -2002,6 +2002,12 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map, | |||
2002 | info.map_flags = map->map_flags; | 2002 | info.map_flags = map->map_flags; |
2003 | memcpy(info.name, map->name, sizeof(map->name)); | 2003 | memcpy(info.name, map->name, sizeof(map->name)); |
2004 | 2004 | ||
2005 | if (map->btf) { | ||
2006 | info.btf_id = btf_id(map->btf); | ||
2007 | info.btf_key_id = map->btf_key_id; | ||
2008 | info.btf_value_id = map->btf_value_id; | ||
2009 | } | ||
2010 | |||
2005 | if (bpf_map_is_dev_bound(map)) { | 2011 | if (bpf_map_is_dev_bound(map)) { |
2006 | err = bpf_map_offload_info_fill(&info, map); | 2012 | err = bpf_map_offload_info_fill(&info, map); |
2007 | if (err) | 2013 | if (err) |
@@ -2059,6 +2065,19 @@ static int bpf_btf_load(const union bpf_attr *attr) | |||
2059 | return btf_new_fd(attr); | 2065 | return btf_new_fd(attr); |
2060 | } | 2066 | } |
2061 | 2067 | ||
2068 | #define BPF_BTF_GET_FD_BY_ID_LAST_FIELD btf_id | ||
2069 | |||
2070 | static int bpf_btf_get_fd_by_id(const union bpf_attr *attr) | ||
2071 | { | ||
2072 | if (CHECK_ATTR(BPF_BTF_GET_FD_BY_ID)) | ||
2073 | return -EINVAL; | ||
2074 | |||
2075 | if (!capable(CAP_SYS_ADMIN)) | ||
2076 | return -EPERM; | ||
2077 | |||
2078 | return btf_get_fd_by_id(attr->btf_id); | ||
2079 | } | ||
2080 | |||
2062 | SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size) | 2081 | SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size) |
2063 | { | 2082 | { |
2064 | union bpf_attr attr = {}; | 2083 | union bpf_attr attr = {}; |
@@ -2142,6 +2161,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz | |||
2142 | case BPF_BTF_LOAD: | 2161 | case BPF_BTF_LOAD: |
2143 | err = bpf_btf_load(&attr); | 2162 | err = bpf_btf_load(&attr); |
2144 | break; | 2163 | break; |
2164 | case BPF_BTF_GET_FD_BY_ID: | ||
2165 | err = bpf_btf_get_fd_by_id(&attr); | ||
2166 | break; | ||
2145 | default: | 2167 | default: |
2146 | err = -EINVAL; | 2168 | err = -EINVAL; |
2147 | break; | 2169 | break; |