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 --- |