syscall.c (79a7f8bdb159d9914b58740f3d31d602a6e4aca8) syscall.c (af2ac3e13e45752af03c8a933f9b6e18841b128b)
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
3 */
4#include <linux/bpf.h>
5#include <linux/bpf_trace.h>
6#include <linux/bpf_lirc.h>
7#include <linux/bpf_verifier.h>
8#include <linux/btf.h>

--- 58 unchanged lines hidden (view full) ---

67 * If we're handed a bigger struct than we know of, ensure all the unknown bits
68 * are 0 - i.e. new user-space does not rely on any kernel feature extensions
69 * we don't know about yet.
70 *
71 * There is a ToCToU between this function call and the following
72 * copy_from_user() call. However, this is not a concern since this function is
73 * meant to be a future-proofing of bits.
74 */
1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
3 */
4#include <linux/bpf.h>
5#include <linux/bpf_trace.h>
6#include <linux/bpf_lirc.h>
7#include <linux/bpf_verifier.h>
8#include <linux/btf.h>

--- 58 unchanged lines hidden (view full) ---

67 * If we're handed a bigger struct than we know of, ensure all the unknown bits
68 * are 0 - i.e. new user-space does not rely on any kernel feature extensions
69 * we don't know about yet.
70 *
71 * There is a ToCToU between this function call and the following
72 * copy_from_user() call. However, this is not a concern since this function is
73 * meant to be a future-proofing of bits.
74 */
75int bpf_check_uarg_tail_zero(void __user *uaddr,
75int bpf_check_uarg_tail_zero(bpfptr_t uaddr,
76 size_t expected_size,
77 size_t actual_size)
78{
76 size_t expected_size,
77 size_t actual_size)
78{
79 unsigned char __user *addr = uaddr + expected_size;
80 int res;
81
82 if (unlikely(actual_size > PAGE_SIZE)) /* silly large */
83 return -E2BIG;
84
85 if (actual_size <= expected_size)
86 return 0;
87
79 int res;
80
81 if (unlikely(actual_size > PAGE_SIZE)) /* silly large */
82 return -E2BIG;
83
84 if (actual_size <= expected_size)
85 return 0;
86
88 res = check_zeroed_user(addr, actual_size - expected_size);
87 if (uaddr.is_kernel)
88 res = memchr_inv(uaddr.kernel + expected_size, 0,
89 actual_size - expected_size) == NULL;
90 else
91 res = check_zeroed_user(uaddr.user + expected_size,
92 actual_size - expected_size);
89 if (res < 0)
90 return res;
91 return res ? 0 : -E2BIG;
92}
93
94const struct bpf_map_ops bpf_map_offload_ops = {
95 .map_meta_equal = bpf_map_meta_equal,
96 .map_alloc = bpf_map_offload_map_alloc,

--- 902 unchanged lines hidden (view full) ---

999 return memdup_user(ukey, key_size);
1000
1001 if (ukey)
1002 return ERR_PTR(-EINVAL);
1003
1004 return NULL;
1005}
1006
93 if (res < 0)
94 return res;
95 return res ? 0 : -E2BIG;
96}
97
98const struct bpf_map_ops bpf_map_offload_ops = {
99 .map_meta_equal = bpf_map_meta_equal,
100 .map_alloc = bpf_map_offload_map_alloc,

--- 902 unchanged lines hidden (view full) ---

1003 return memdup_user(ukey, key_size);
1004
1005 if (ukey)
1006 return ERR_PTR(-EINVAL);
1007
1008 return NULL;
1009}
1010
1011static void *___bpf_copy_key(bpfptr_t ukey, u64 key_size)
1012{
1013 if (key_size)
1014 return memdup_bpfptr(ukey, key_size);
1015
1016 if (!bpfptr_is_null(ukey))
1017 return ERR_PTR(-EINVAL);
1018
1019 return NULL;
1020}
1021
1007/* last field in 'union bpf_attr' used by this command */
1008#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD flags
1009
1010static int map_lookup_elem(union bpf_attr *attr)
1011{
1012 void __user *ukey = u64_to_user_ptr(attr->key);
1013 void __user *uvalue = u64_to_user_ptr(attr->value);
1014 int ufd = attr->map_fd;

--- 54 unchanged lines hidden (view full) ---

1069err_put:
1070 fdput(f);
1071 return err;
1072}
1073
1074
1075#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags
1076
1022/* last field in 'union bpf_attr' used by this command */
1023#define BPF_MAP_LOOKUP_ELEM_LAST_FIELD flags
1024
1025static int map_lookup_elem(union bpf_attr *attr)
1026{
1027 void __user *ukey = u64_to_user_ptr(attr->key);
1028 void __user *uvalue = u64_to_user_ptr(attr->value);
1029 int ufd = attr->map_fd;

--- 54 unchanged lines hidden (view full) ---

1084err_put:
1085 fdput(f);
1086 return err;
1087}
1088
1089
1090#define BPF_MAP_UPDATE_ELEM_LAST_FIELD flags
1091
1077static int map_update_elem(union bpf_attr *attr)
1092static int map_update_elem(union bpf_attr *attr, bpfptr_t uattr)
1078{
1093{
1079 void __user *ukey = u64_to_user_ptr(attr->key);
1080 void __user *uvalue = u64_to_user_ptr(attr->value);
1094 bpfptr_t ukey = make_bpfptr(attr->key, uattr.is_kernel);
1095 bpfptr_t uvalue = make_bpfptr(attr->value, uattr.is_kernel);
1081 int ufd = attr->map_fd;
1082 struct bpf_map *map;
1083 void *key, *value;
1084 u32 value_size;
1085 struct fd f;
1086 int err;
1087
1088 if (CHECK_ATTR(BPF_MAP_UPDATE_ELEM))

--- 9 unchanged lines hidden (view full) ---

1098 }
1099
1100 if ((attr->flags & BPF_F_LOCK) &&
1101 !map_value_has_spin_lock(map)) {
1102 err = -EINVAL;
1103 goto err_put;
1104 }
1105
1096 int ufd = attr->map_fd;
1097 struct bpf_map *map;
1098 void *key, *value;
1099 u32 value_size;
1100 struct fd f;
1101 int err;
1102
1103 if (CHECK_ATTR(BPF_MAP_UPDATE_ELEM))

--- 9 unchanged lines hidden (view full) ---

1113 }
1114
1115 if ((attr->flags & BPF_F_LOCK) &&
1116 !map_value_has_spin_lock(map)) {
1117 err = -EINVAL;
1118 goto err_put;
1119 }
1120
1106 key = __bpf_copy_key(ukey, map->key_size);
1121 key = ___bpf_copy_key(ukey, map->key_size);
1107 if (IS_ERR(key)) {
1108 err = PTR_ERR(key);
1109 goto err_put;
1110 }
1111
1112 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
1113 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
1114 map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY ||
1115 map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
1116 value_size = round_up(map->value_size, 8) * num_possible_cpus();
1117 else
1118 value_size = map->value_size;
1119
1120 err = -ENOMEM;
1121 value = kmalloc(value_size, GFP_USER | __GFP_NOWARN);
1122 if (!value)
1123 goto free_key;
1124
1125 err = -EFAULT;
1122 if (IS_ERR(key)) {
1123 err = PTR_ERR(key);
1124 goto err_put;
1125 }
1126
1127 if (map->map_type == BPF_MAP_TYPE_PERCPU_HASH ||
1128 map->map_type == BPF_MAP_TYPE_LRU_PERCPU_HASH ||
1129 map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY ||
1130 map->map_type == BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE)
1131 value_size = round_up(map->value_size, 8) * num_possible_cpus();
1132 else
1133 value_size = map->value_size;
1134
1135 err = -ENOMEM;
1136 value = kmalloc(value_size, GFP_USER | __GFP_NOWARN);
1137 if (!value)
1138 goto free_key;
1139
1140 err = -EFAULT;
1126 if (copy_from_user(value, uvalue, value_size) != 0)
1141 if (copy_from_bpfptr(value, uvalue, value_size) != 0)
1127 goto free_value;
1128
1129 err = bpf_map_update_value(map, f, key, value, attr->flags);
1130
1131free_value:
1132 kfree(value);
1133free_key:
1134 kfree(key);

--- 936 unchanged lines hidden (view full) ---

2071 default:
2072 return false;
2073 }
2074}
2075
2076/* last field in 'union bpf_attr' used by this command */
2077#define BPF_PROG_LOAD_LAST_FIELD attach_prog_fd
2078
1142 goto free_value;
1143
1144 err = bpf_map_update_value(map, f, key, value, attr->flags);
1145
1146free_value:
1147 kfree(value);
1148free_key:
1149 kfree(key);

--- 936 unchanged lines hidden (view full) ---

2086 default:
2087 return false;
2088 }
2089}
2090
2091/* last field in 'union bpf_attr' used by this command */
2092#define BPF_PROG_LOAD_LAST_FIELD attach_prog_fd
2093
2079static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
2094static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr)
2080{
2081 enum bpf_prog_type type = attr->prog_type;
2082 struct bpf_prog *prog, *dst_prog = NULL;
2083 struct btf *attach_btf = NULL;
2084 int err;
2085 char license[128];
2086 bool is_gpl;
2087

--- 8 unchanged lines hidden (view full) ---

2096 return -EINVAL;
2097
2098 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
2099 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
2100 !bpf_capable())
2101 return -EPERM;
2102
2103 /* copy eBPF program license from user space */
2095{
2096 enum bpf_prog_type type = attr->prog_type;
2097 struct bpf_prog *prog, *dst_prog = NULL;
2098 struct btf *attach_btf = NULL;
2099 int err;
2100 char license[128];
2101 bool is_gpl;
2102

--- 8 unchanged lines hidden (view full) ---

2111 return -EINVAL;
2112
2113 if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) &&
2114 (attr->prog_flags & BPF_F_ANY_ALIGNMENT) &&
2115 !bpf_capable())
2116 return -EPERM;
2117
2118 /* copy eBPF program license from user space */
2104 if (strncpy_from_user(license, u64_to_user_ptr(attr->license),
2105 sizeof(license) - 1) < 0)
2119 if (strncpy_from_bpfptr(license,
2120 make_bpfptr(attr->license, uattr.is_kernel),
2121 sizeof(license) - 1) < 0)
2106 return -EFAULT;
2107 license[sizeof(license) - 1] = 0;
2108
2109 /* eBPF programs must be GPL compatible to use GPL-ed functions */
2110 is_gpl = license_is_gpl_compatible(license);
2111
2112 if (attr->insn_cnt == 0 ||
2113 attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))

--- 67 unchanged lines hidden (view full) ---

2181 err = security_bpf_prog_alloc(prog->aux);
2182 if (err)
2183 goto free_prog;
2184
2185 prog->aux->user = get_current_user();
2186 prog->len = attr->insn_cnt;
2187
2188 err = -EFAULT;
2122 return -EFAULT;
2123 license[sizeof(license) - 1] = 0;
2124
2125 /* eBPF programs must be GPL compatible to use GPL-ed functions */
2126 is_gpl = license_is_gpl_compatible(license);
2127
2128 if (attr->insn_cnt == 0 ||
2129 attr->insn_cnt > (bpf_capable() ? BPF_COMPLEXITY_LIMIT_INSNS : BPF_MAXINSNS))

--- 67 unchanged lines hidden (view full) ---

2197 err = security_bpf_prog_alloc(prog->aux);
2198 if (err)
2199 goto free_prog;
2200
2201 prog->aux->user = get_current_user();
2202 prog->len = attr->insn_cnt;
2203
2204 err = -EFAULT;
2189 if (copy_from_user(prog->insns, u64_to_user_ptr(attr->insns),
2190 bpf_prog_insn_size(prog)) != 0)
2205 if (copy_from_bpfptr(prog->insns,
2206 make_bpfptr(attr->insns, uattr.is_kernel),
2207 bpf_prog_insn_size(prog)) != 0)
2191 goto free_prog_sec;
2192
2193 prog->orig_prog = NULL;
2194 prog->jited = 0;
2195
2196 atomic64_set(&prog->aux->refcnt, 1);
2197 prog->gpl_compatible = is_gpl ? 1 : 0;
2198

--- 1219 unchanged lines hidden (view full) ---

3418 struct bpf_prog_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3419 struct bpf_prog_info info;
3420 u32 info_len = attr->info.info_len;
3421 struct bpf_prog_stats stats;
3422 char __user *uinsns;
3423 u32 ulen;
3424 int err;
3425
2208 goto free_prog_sec;
2209
2210 prog->orig_prog = NULL;
2211 prog->jited = 0;
2212
2213 atomic64_set(&prog->aux->refcnt, 1);
2214 prog->gpl_compatible = is_gpl ? 1 : 0;
2215

--- 1219 unchanged lines hidden (view full) ---

3435 struct bpf_prog_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3436 struct bpf_prog_info info;
3437 u32 info_len = attr->info.info_len;
3438 struct bpf_prog_stats stats;
3439 char __user *uinsns;
3440 u32 ulen;
3441 int err;
3442
3426 err = bpf_check_uarg_tail_zero(uinfo, sizeof(info), info_len);
3443 err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), sizeof(info), info_len);
3427 if (err)
3428 return err;
3429 info_len = min_t(u32, sizeof(info), info_len);
3430
3431 memset(&info, 0, sizeof(info));
3432 if (copy_from_user(&info, uinfo, info_len))
3433 return -EFAULT;
3434

--- 262 unchanged lines hidden (view full) ---

3697 const union bpf_attr *attr,
3698 union bpf_attr __user *uattr)
3699{
3700 struct bpf_map_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3701 struct bpf_map_info info;
3702 u32 info_len = attr->info.info_len;
3703 int err;
3704
3444 if (err)
3445 return err;
3446 info_len = min_t(u32, sizeof(info), info_len);
3447
3448 memset(&info, 0, sizeof(info));
3449 if (copy_from_user(&info, uinfo, info_len))
3450 return -EFAULT;
3451

--- 262 unchanged lines hidden (view full) ---

3714 const union bpf_attr *attr,
3715 union bpf_attr __user *uattr)
3716{
3717 struct bpf_map_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3718 struct bpf_map_info info;
3719 u32 info_len = attr->info.info_len;
3720 int err;
3721
3705 err = bpf_check_uarg_tail_zero(uinfo, sizeof(info), info_len);
3722 err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), sizeof(info), info_len);
3706 if (err)
3707 return err;
3708 info_len = min_t(u32, sizeof(info), info_len);
3709
3710 memset(&info, 0, sizeof(info));
3711 info.type = map->map_type;
3712 info.id = map->id;
3713 info.key_size = map->key_size;

--- 26 unchanged lines hidden (view full) ---

3740 struct btf *btf,
3741 const union bpf_attr *attr,
3742 union bpf_attr __user *uattr)
3743{
3744 struct bpf_btf_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3745 u32 info_len = attr->info.info_len;
3746 int err;
3747
3723 if (err)
3724 return err;
3725 info_len = min_t(u32, sizeof(info), info_len);
3726
3727 memset(&info, 0, sizeof(info));
3728 info.type = map->map_type;
3729 info.id = map->id;
3730 info.key_size = map->key_size;

--- 26 unchanged lines hidden (view full) ---

3757 struct btf *btf,
3758 const union bpf_attr *attr,
3759 union bpf_attr __user *uattr)
3760{
3761 struct bpf_btf_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3762 u32 info_len = attr->info.info_len;
3763 int err;
3764
3748 err = bpf_check_uarg_tail_zero(uinfo, sizeof(*uinfo), info_len);
3765 err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), sizeof(*uinfo), info_len);
3749 if (err)
3750 return err;
3751
3752 return btf_get_info_by_fd(btf, attr, uattr);
3753}
3754
3755static int bpf_link_get_info_by_fd(struct file *file,
3756 struct bpf_link *link,
3757 const union bpf_attr *attr,
3758 union bpf_attr __user *uattr)
3759{
3760 struct bpf_link_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3761 struct bpf_link_info info;
3762 u32 info_len = attr->info.info_len;
3763 int err;
3764
3766 if (err)
3767 return err;
3768
3769 return btf_get_info_by_fd(btf, attr, uattr);
3770}
3771
3772static int bpf_link_get_info_by_fd(struct file *file,
3773 struct bpf_link *link,
3774 const union bpf_attr *attr,
3775 union bpf_attr __user *uattr)
3776{
3777 struct bpf_link_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3778 struct bpf_link_info info;
3779 u32 info_len = attr->info.info_len;
3780 int err;
3781
3765 err = bpf_check_uarg_tail_zero(uinfo, sizeof(info), info_len);
3782 err = bpf_check_uarg_tail_zero(USER_BPFPTR(uinfo), sizeof(info), info_len);
3766 if (err)
3767 return err;
3768 info_len = min_t(u32, sizeof(info), info_len);
3769
3770 memset(&info, 0, sizeof(info));
3771 if (copy_from_user(&info, uinfo, info_len))
3772 return -EFAULT;
3773

--- 244 unchanged lines hidden (view full) ---

4018 else
4019 BPF_DO_BATCH(map->ops->map_delete_batch);
4020
4021err_put:
4022 fdput(f);
4023 return err;
4024}
4025
3783 if (err)
3784 return err;
3785 info_len = min_t(u32, sizeof(info), info_len);
3786
3787 memset(&info, 0, sizeof(info));
3788 if (copy_from_user(&info, uinfo, info_len))
3789 return -EFAULT;
3790

--- 244 unchanged lines hidden (view full) ---

4035 else
4036 BPF_DO_BATCH(map->ops->map_delete_batch);
4037
4038err_put:
4039 fdput(f);
4040 return err;
4041}
4042
4026static int tracing_bpf_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
4043static int tracing_bpf_link_attach(const union bpf_attr *attr, bpfptr_t uattr,
4044 struct bpf_prog *prog)
4027{
4028 if (attr->link_create.attach_type != prog->expected_attach_type)
4029 return -EINVAL;
4030
4031 if (prog->expected_attach_type == BPF_TRACE_ITER)
4045{
4046 if (attr->link_create.attach_type != prog->expected_attach_type)
4047 return -EINVAL;
4048
4049 if (prog->expected_attach_type == BPF_TRACE_ITER)
4032 return bpf_iter_link_attach(attr, prog);
4050 return bpf_iter_link_attach(attr, uattr, prog);
4033 else if (prog->type == BPF_PROG_TYPE_EXT)
4034 return bpf_tracing_prog_attach(prog,
4035 attr->link_create.target_fd,
4036 attr->link_create.target_btf_id);
4037 return -EINVAL;
4038}
4039
4040#define BPF_LINK_CREATE_LAST_FIELD link_create.iter_info_len
4051 else if (prog->type == BPF_PROG_TYPE_EXT)
4052 return bpf_tracing_prog_attach(prog,
4053 attr->link_create.target_fd,
4054 attr->link_create.target_btf_id);
4055 return -EINVAL;
4056}
4057
4058#define BPF_LINK_CREATE_LAST_FIELD link_create.iter_info_len
4041static int link_create(union bpf_attr *attr)
4059static int link_create(union bpf_attr *attr, bpfptr_t uattr)
4042{
4043 enum bpf_prog_type ptype;
4044 struct bpf_prog *prog;
4045 int ret;
4046
4047 if (CHECK_ATTR(BPF_LINK_CREATE))
4048 return -EINVAL;
4049
4050 prog = bpf_prog_get(attr->link_create.prog_fd);
4051 if (IS_ERR(prog))
4052 return PTR_ERR(prog);
4053
4054 ret = bpf_prog_attach_check_attach_type(prog,
4055 attr->link_create.attach_type);
4056 if (ret)
4057 goto out;
4058
4059 if (prog->type == BPF_PROG_TYPE_EXT) {
4060{
4061 enum bpf_prog_type ptype;
4062 struct bpf_prog *prog;
4063 int ret;
4064
4065 if (CHECK_ATTR(BPF_LINK_CREATE))
4066 return -EINVAL;
4067
4068 prog = bpf_prog_get(attr->link_create.prog_fd);
4069 if (IS_ERR(prog))
4070 return PTR_ERR(prog);
4071
4072 ret = bpf_prog_attach_check_attach_type(prog,
4073 attr->link_create.attach_type);
4074 if (ret)
4075 goto out;
4076
4077 if (prog->type == BPF_PROG_TYPE_EXT) {
4060 ret = tracing_bpf_link_attach(attr, prog);
4078 ret = tracing_bpf_link_attach(attr, uattr, prog);
4061 goto out;
4062 }
4063
4064 ptype = attach_type_to_prog_type(attr->link_create.attach_type);
4065 if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type) {
4066 ret = -EINVAL;
4067 goto out;
4068 }

--- 4 unchanged lines hidden (view full) ---

4073 case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
4074 case BPF_PROG_TYPE_SOCK_OPS:
4075 case BPF_PROG_TYPE_CGROUP_DEVICE:
4076 case BPF_PROG_TYPE_CGROUP_SYSCTL:
4077 case BPF_PROG_TYPE_CGROUP_SOCKOPT:
4078 ret = cgroup_bpf_link_attach(attr, prog);
4079 break;
4080 case BPF_PROG_TYPE_TRACING:
4079 goto out;
4080 }
4081
4082 ptype = attach_type_to_prog_type(attr->link_create.attach_type);
4083 if (ptype == BPF_PROG_TYPE_UNSPEC || ptype != prog->type) {
4084 ret = -EINVAL;
4085 goto out;
4086 }

--- 4 unchanged lines hidden (view full) ---

4091 case BPF_PROG_TYPE_CGROUP_SOCK_ADDR:
4092 case BPF_PROG_TYPE_SOCK_OPS:
4093 case BPF_PROG_TYPE_CGROUP_DEVICE:
4094 case BPF_PROG_TYPE_CGROUP_SYSCTL:
4095 case BPF_PROG_TYPE_CGROUP_SOCKOPT:
4096 ret = cgroup_bpf_link_attach(attr, prog);
4097 break;
4098 case BPF_PROG_TYPE_TRACING:
4081 ret = tracing_bpf_link_attach(attr, prog);
4099 ret = tracing_bpf_link_attach(attr, uattr, prog);
4082 break;
4083 case BPF_PROG_TYPE_FLOW_DISSECTOR:
4084 case BPF_PROG_TYPE_SK_LOOKUP:
4085 ret = netns_bpf_link_create(attr, prog);
4086 break;
4087#ifdef CONFIG_NET
4088 case BPF_PROG_TYPE_XDP:
4089 ret = bpf_xdp_link_attach(attr, prog);

--- 271 unchanged lines hidden (view full) ---

4361
4362 if (ret)
4363 bpf_map_put(map);
4364out_prog_put:
4365 bpf_prog_put(prog);
4366 return ret;
4367}
4368
4100 break;
4101 case BPF_PROG_TYPE_FLOW_DISSECTOR:
4102 case BPF_PROG_TYPE_SK_LOOKUP:
4103 ret = netns_bpf_link_create(attr, prog);
4104 break;
4105#ifdef CONFIG_NET
4106 case BPF_PROG_TYPE_XDP:
4107 ret = bpf_xdp_link_attach(attr, prog);

--- 271 unchanged lines hidden (view full) ---

4379
4380 if (ret)
4381 bpf_map_put(map);
4382out_prog_put:
4383 bpf_prog_put(prog);
4384 return ret;
4385}
4386
4369SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
4387static int __sys_bpf(int cmd, bpfptr_t uattr, unsigned int size)
4370{
4371 union bpf_attr attr;
4372 int err;
4373
4374 if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
4375 return -EPERM;
4376
4377 err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size);
4378 if (err)
4379 return err;
4380 size = min_t(u32, size, sizeof(attr));
4381
4382 /* copy attributes from user space, may be less than sizeof(bpf_attr) */
4383 memset(&attr, 0, sizeof(attr));
4388{
4389 union bpf_attr attr;
4390 int err;
4391
4392 if (sysctl_unprivileged_bpf_disabled && !bpf_capable())
4393 return -EPERM;
4394
4395 err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size);
4396 if (err)
4397 return err;
4398 size = min_t(u32, size, sizeof(attr));
4399
4400 /* copy attributes from user space, may be less than sizeof(bpf_attr) */
4401 memset(&attr, 0, sizeof(attr));
4384 if (copy_from_user(&attr, uattr, size) != 0)
4402 if (copy_from_bpfptr(&attr, uattr, size) != 0)
4385 return -EFAULT;
4386
4387 err = security_bpf(cmd, &attr, size);
4388 if (err < 0)
4389 return err;
4390
4391 switch (cmd) {
4392 case BPF_MAP_CREATE:
4393 err = map_create(&attr);
4394 break;
4395 case BPF_MAP_LOOKUP_ELEM:
4396 err = map_lookup_elem(&attr);
4397 break;
4398 case BPF_MAP_UPDATE_ELEM:
4403 return -EFAULT;
4404
4405 err = security_bpf(cmd, &attr, size);
4406 if (err < 0)
4407 return err;
4408
4409 switch (cmd) {
4410 case BPF_MAP_CREATE:
4411 err = map_create(&attr);
4412 break;
4413 case BPF_MAP_LOOKUP_ELEM:
4414 err = map_lookup_elem(&attr);
4415 break;
4416 case BPF_MAP_UPDATE_ELEM:
4399 err = map_update_elem(&attr);
4417 err = map_update_elem(&attr, uattr);
4400 break;
4401 case BPF_MAP_DELETE_ELEM:
4402 err = map_delete_elem(&attr);
4403 break;
4404 case BPF_MAP_GET_NEXT_KEY:
4405 err = map_get_next_key(&attr);
4406 break;
4407 case BPF_MAP_FREEZE:

--- 10 unchanged lines hidden (view full) ---

4418 break;
4419 case BPF_PROG_ATTACH:
4420 err = bpf_prog_attach(&attr);
4421 break;
4422 case BPF_PROG_DETACH:
4423 err = bpf_prog_detach(&attr);
4424 break;
4425 case BPF_PROG_QUERY:
4418 break;
4419 case BPF_MAP_DELETE_ELEM:
4420 err = map_delete_elem(&attr);
4421 break;
4422 case BPF_MAP_GET_NEXT_KEY:
4423 err = map_get_next_key(&attr);
4424 break;
4425 case BPF_MAP_FREEZE:

--- 10 unchanged lines hidden (view full) ---

4436 break;
4437 case BPF_PROG_ATTACH:
4438 err = bpf_prog_attach(&attr);
4439 break;
4440 case BPF_PROG_DETACH:
4441 err = bpf_prog_detach(&attr);
4442 break;
4443 case BPF_PROG_QUERY:
4426 err = bpf_prog_query(&attr, uattr);
4444 err = bpf_prog_query(&attr, uattr.user);
4427 break;
4428 case BPF_PROG_TEST_RUN:
4445 break;
4446 case BPF_PROG_TEST_RUN:
4429 err = bpf_prog_test_run(&attr, uattr);
4447 err = bpf_prog_test_run(&attr, uattr.user);
4430 break;
4431 case BPF_PROG_GET_NEXT_ID:
4448 break;
4449 case BPF_PROG_GET_NEXT_ID:
4432 err = bpf_obj_get_next_id(&attr, uattr,
4450 err = bpf_obj_get_next_id(&attr, uattr.user,
4433 &prog_idr, &prog_idr_lock);
4434 break;
4435 case BPF_MAP_GET_NEXT_ID:
4451 &prog_idr, &prog_idr_lock);
4452 break;
4453 case BPF_MAP_GET_NEXT_ID:
4436 err = bpf_obj_get_next_id(&attr, uattr,
4454 err = bpf_obj_get_next_id(&attr, uattr.user,
4437 &map_idr, &map_idr_lock);
4438 break;
4439 case BPF_BTF_GET_NEXT_ID:
4455 &map_idr, &map_idr_lock);
4456 break;
4457 case BPF_BTF_GET_NEXT_ID:
4440 err = bpf_obj_get_next_id(&attr, uattr,
4458 err = bpf_obj_get_next_id(&attr, uattr.user,
4441 &btf_idr, &btf_idr_lock);
4442 break;
4443 case BPF_PROG_GET_FD_BY_ID:
4444 err = bpf_prog_get_fd_by_id(&attr);
4445 break;
4446 case BPF_MAP_GET_FD_BY_ID:
4447 err = bpf_map_get_fd_by_id(&attr);
4448 break;
4449 case BPF_OBJ_GET_INFO_BY_FD:
4459 &btf_idr, &btf_idr_lock);
4460 break;
4461 case BPF_PROG_GET_FD_BY_ID:
4462 err = bpf_prog_get_fd_by_id(&attr);
4463 break;
4464 case BPF_MAP_GET_FD_BY_ID:
4465 err = bpf_map_get_fd_by_id(&attr);
4466 break;
4467 case BPF_OBJ_GET_INFO_BY_FD:
4450 err = bpf_obj_get_info_by_fd(&attr, uattr);
4468 err = bpf_obj_get_info_by_fd(&attr, uattr.user);
4451 break;
4452 case BPF_RAW_TRACEPOINT_OPEN:
4453 err = bpf_raw_tracepoint_open(&attr);
4454 break;
4455 case BPF_BTF_LOAD:
4456 err = bpf_btf_load(&attr);
4457 break;
4458 case BPF_BTF_GET_FD_BY_ID:
4459 err = bpf_btf_get_fd_by_id(&attr);
4460 break;
4461 case BPF_TASK_FD_QUERY:
4469 break;
4470 case BPF_RAW_TRACEPOINT_OPEN:
4471 err = bpf_raw_tracepoint_open(&attr);
4472 break;
4473 case BPF_BTF_LOAD:
4474 err = bpf_btf_load(&attr);
4475 break;
4476 case BPF_BTF_GET_FD_BY_ID:
4477 err = bpf_btf_get_fd_by_id(&attr);
4478 break;
4479 case BPF_TASK_FD_QUERY:
4462 err = bpf_task_fd_query(&attr, uattr);
4480 err = bpf_task_fd_query(&attr, uattr.user);
4463 break;
4464 case BPF_MAP_LOOKUP_AND_DELETE_ELEM:
4465 err = map_lookup_and_delete_elem(&attr);
4466 break;
4467 case BPF_MAP_LOOKUP_BATCH:
4481 break;
4482 case BPF_MAP_LOOKUP_AND_DELETE_ELEM:
4483 err = map_lookup_and_delete_elem(&attr);
4484 break;
4485 case BPF_MAP_LOOKUP_BATCH:
4468 err = bpf_map_do_batch(&attr, uattr, BPF_MAP_LOOKUP_BATCH);
4486 err = bpf_map_do_batch(&attr, uattr.user, BPF_MAP_LOOKUP_BATCH);
4469 break;
4470 case BPF_MAP_LOOKUP_AND_DELETE_BATCH:
4487 break;
4488 case BPF_MAP_LOOKUP_AND_DELETE_BATCH:
4471 err = bpf_map_do_batch(&attr, uattr,
4489 err = bpf_map_do_batch(&attr, uattr.user,
4472 BPF_MAP_LOOKUP_AND_DELETE_BATCH);
4473 break;
4474 case BPF_MAP_UPDATE_BATCH:
4490 BPF_MAP_LOOKUP_AND_DELETE_BATCH);
4491 break;
4492 case BPF_MAP_UPDATE_BATCH:
4475 err = bpf_map_do_batch(&attr, uattr, BPF_MAP_UPDATE_BATCH);
4493 err = bpf_map_do_batch(&attr, uattr.user, BPF_MAP_UPDATE_BATCH);
4476 break;
4477 case BPF_MAP_DELETE_BATCH:
4494 break;
4495 case BPF_MAP_DELETE_BATCH:
4478 err = bpf_map_do_batch(&attr, uattr, BPF_MAP_DELETE_BATCH);
4496 err = bpf_map_do_batch(&attr, uattr.user, BPF_MAP_DELETE_BATCH);
4479 break;
4480 case BPF_LINK_CREATE:
4497 break;
4498 case BPF_LINK_CREATE:
4481 err = link_create(&attr);
4499 err = link_create(&attr, uattr);
4482 break;
4483 case BPF_LINK_UPDATE:
4484 err = link_update(&attr);
4485 break;
4486 case BPF_LINK_GET_FD_BY_ID:
4487 err = bpf_link_get_fd_by_id(&attr);
4488 break;
4489 case BPF_LINK_GET_NEXT_ID:
4500 break;
4501 case BPF_LINK_UPDATE:
4502 err = link_update(&attr);
4503 break;
4504 case BPF_LINK_GET_FD_BY_ID:
4505 err = bpf_link_get_fd_by_id(&attr);
4506 break;
4507 case BPF_LINK_GET_NEXT_ID:
4490 err = bpf_obj_get_next_id(&attr, uattr,
4508 err = bpf_obj_get_next_id(&attr, uattr.user,
4491 &link_idr, &link_idr_lock);
4492 break;
4493 case BPF_ENABLE_STATS:
4494 err = bpf_enable_stats(&attr);
4495 break;
4496 case BPF_ITER_CREATE:
4497 err = bpf_iter_create(&attr);
4498 break;

--- 6 unchanged lines hidden (view full) ---

4505 default:
4506 err = -EINVAL;
4507 break;
4508 }
4509
4510 return err;
4511}
4512
4509 &link_idr, &link_idr_lock);
4510 break;
4511 case BPF_ENABLE_STATS:
4512 err = bpf_enable_stats(&attr);
4513 break;
4514 case BPF_ITER_CREATE:
4515 err = bpf_iter_create(&attr);
4516 break;

--- 6 unchanged lines hidden (view full) ---

4523 default:
4524 err = -EINVAL;
4525 break;
4526 }
4527
4528 return err;
4529}
4530
4531SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
4532{
4533 return __sys_bpf(cmd, USER_BPFPTR(uattr), size);
4534}
4535
4513static bool syscall_prog_is_valid_access(int off, int size,
4514 enum bpf_access_type type,
4515 const struct bpf_prog *prog,
4516 struct bpf_insn_access_aux *info)
4517{
4518 if (off < 0 || off >= U16_MAX)
4519 return false;
4520 if (off % size != 0)
4521 return false;
4522 return true;
4523}
4524
4525BPF_CALL_3(bpf_sys_bpf, int, cmd, void *, attr, u32, attr_size)
4526{
4536static bool syscall_prog_is_valid_access(int off, int size,
4537 enum bpf_access_type type,
4538 const struct bpf_prog *prog,
4539 struct bpf_insn_access_aux *info)
4540{
4541 if (off < 0 || off >= U16_MAX)
4542 return false;
4543 if (off % size != 0)
4544 return false;
4545 return true;
4546}
4547
4548BPF_CALL_3(bpf_sys_bpf, int, cmd, void *, attr, u32, attr_size)
4549{
4527 return -EINVAL;
4550 switch (cmd) {
4551 case BPF_MAP_CREATE:
4552 case BPF_MAP_UPDATE_ELEM:
4553 case BPF_MAP_FREEZE:
4554 case BPF_PROG_LOAD:
4555 break;
4556 /* case BPF_PROG_TEST_RUN:
4557 * is not part of this list to prevent recursive test_run
4558 */
4559 default:
4560 return -EINVAL;
4561 }
4562 return __sys_bpf(cmd, KERNEL_BPFPTR(attr), attr_size);
4528}
4529
4530const struct bpf_func_proto bpf_sys_bpf_proto = {
4531 .func = bpf_sys_bpf,
4532 .gpl_only = false,
4533 .ret_type = RET_INTEGER,
4534 .arg1_type = ARG_ANYTHING,
4535 .arg2_type = ARG_PTR_TO_MEM,

--- 28 unchanged lines hidden ---
4563}
4564
4565const struct bpf_func_proto bpf_sys_bpf_proto = {
4566 .func = bpf_sys_bpf,
4567 .gpl_only = false,
4568 .ret_type = RET_INTEGER,
4569 .arg1_type = ARG_ANYTHING,
4570 .arg2_type = ARG_PTR_TO_MEM,

--- 28 unchanged lines hidden ---