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.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 4c3075b5d840..2405feedb8c1 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -166,6 +166,7 @@ static void bpf_map_put_uref(struct bpf_map *map)
166void bpf_map_put(struct bpf_map *map) 166void bpf_map_put(struct bpf_map *map)
167{ 167{
168 if (atomic_dec_and_test(&map->refcnt)) { 168 if (atomic_dec_and_test(&map->refcnt)) {
169 /* bpf_map_free_id() must be called first */
169 bpf_map_free_id(map); 170 bpf_map_free_id(map);
170 INIT_WORK(&map->work, bpf_map_free_deferred); 171 INIT_WORK(&map->work, bpf_map_free_deferred);
171 schedule_work(&map->work); 172 schedule_work(&map->work);
@@ -726,6 +727,7 @@ void bpf_prog_put(struct bpf_prog *prog)
726{ 727{
727 if (atomic_dec_and_test(&prog->aux->refcnt)) { 728 if (atomic_dec_and_test(&prog->aux->refcnt)) {
728 trace_bpf_prog_put_rcu(prog); 729 trace_bpf_prog_put_rcu(prog);
730 /* bpf_prog_free_id() must be called first */
729 bpf_prog_free_id(prog); 731 bpf_prog_free_id(prog);
730 bpf_prog_kallsyms_del(prog); 732 bpf_prog_kallsyms_del(prog);
731 call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu); 733 call_rcu(&prog->aux->rcu, __bpf_prog_put_rcu);
@@ -1069,6 +1071,34 @@ static int bpf_prog_test_run(const union bpf_attr *attr,
1069 return ret; 1071 return ret;
1070} 1072}
1071 1073
1074#define BPF_OBJ_GET_NEXT_ID_LAST_FIELD next_id
1075
1076static int bpf_obj_get_next_id(const union bpf_attr *attr,
1077 union bpf_attr __user *uattr,
1078 struct idr *idr,
1079 spinlock_t *lock)
1080{
1081 u32 next_id = attr->start_id;
1082 int err = 0;
1083
1084 if (CHECK_ATTR(BPF_OBJ_GET_NEXT_ID) || next_id >= INT_MAX)
1085 return -EINVAL;
1086
1087 if (!capable(CAP_SYS_ADMIN))
1088 return -EPERM;
1089
1090 next_id++;
1091 spin_lock_bh(lock);
1092 if (!idr_get_next(idr, &next_id))
1093 err = -ENOENT;
1094 spin_unlock_bh(lock);
1095
1096 if (!err)
1097 err = put_user(next_id, &uattr->next_id);
1098
1099 return err;
1100}
1101
1072SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size) 1102SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
1073{ 1103{
1074 union bpf_attr attr = {}; 1104 union bpf_attr attr = {};
@@ -1146,6 +1176,14 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
1146 case BPF_PROG_TEST_RUN: 1176 case BPF_PROG_TEST_RUN:
1147 err = bpf_prog_test_run(&attr, uattr); 1177 err = bpf_prog_test_run(&attr, uattr);
1148 break; 1178 break;
1179 case BPF_PROG_GET_NEXT_ID:
1180 err = bpf_obj_get_next_id(&attr, uattr,
1181 &prog_idr, &prog_idr_lock);
1182 break;
1183 case BPF_MAP_GET_NEXT_ID:
1184 err = bpf_obj_get_next_id(&attr, uattr,
1185 &map_idr, &map_idr_lock);
1186 break;
1149 default: 1187 default:
1150 err = -EINVAL; 1188 err = -EINVAL;
1151 break; 1189 break;