Skip to content

Commit a0ba26f

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2020-03-27 The following pull-request contains BPF updates for your *net* tree. We've added 3 non-merge commits during the last 4 day(s) which contain a total of 4 files changed, 25 insertions(+), 20 deletions(-). The main changes are: 1) Explicitly memset the bpf_attr structure on bpf() syscall to avoid having to rely on compiler to do so. Issues have been noticed on some compilers with padding and other oddities where the request was then unexpectedly rejected, from Greg Kroah-Hartman. 2) Sanitize the bpf_struct_ops TCP congestion control name in order to avoid problematic characters such as whitespaces, from Martin KaFai Lau. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 2e8c339 + 5c6f258 commit a0ba26f

File tree

4 files changed

+25
-20
lines changed

4 files changed

+25
-20
lines changed

include/linux/bpf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ static inline void copy_map_value(struct bpf_map *map, void *dst, void *src)
160160
}
161161
void copy_map_value_locked(struct bpf_map *map, void *dst, void *src,
162162
bool lock_src);
163+
int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size);
163164

164165
struct bpf_offload_dev;
165166
struct bpf_offloaded_map;

kernel/bpf/btf.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4564,7 +4564,7 @@ int btf_get_info_by_fd(const struct btf *btf,
45644564
union bpf_attr __user *uattr)
45654565
{
45664566
struct bpf_btf_info __user *uinfo;
4567-
struct bpf_btf_info info = {};
4567+
struct bpf_btf_info info;
45684568
u32 info_copy, btf_copy;
45694569
void __user *ubtf;
45704570
u32 uinfo_len;
@@ -4573,6 +4573,7 @@ int btf_get_info_by_fd(const struct btf *btf,
45734573
uinfo_len = attr->info.info_len;
45744574

45754575
info_copy = min_t(u32, uinfo_len, sizeof(info));
4576+
memset(&info, 0, sizeof(info));
45764577
if (copy_from_user(&info, uinfo, info_copy))
45774578
return -EFAULT;
45784579

kernel/bpf/syscall.c

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -696,14 +696,15 @@ int bpf_get_file_flag(int flags)
696696
offsetof(union bpf_attr, CMD##_LAST_FIELD) - \
697697
sizeof(attr->CMD##_LAST_FIELD)) != NULL
698698

699-
/* dst and src must have at least BPF_OBJ_NAME_LEN number of bytes.
700-
* Return 0 on success and < 0 on error.
699+
/* dst and src must have at least "size" number of bytes.
700+
* Return strlen on success and < 0 on error.
701701
*/
702-
static int bpf_obj_name_cpy(char *dst, const char *src)
702+
int bpf_obj_name_cpy(char *dst, const char *src, unsigned int size)
703703
{
704-
const char *end = src + BPF_OBJ_NAME_LEN;
704+
const char *end = src + size;
705+
const char *orig_src = src;
705706

706-
memset(dst, 0, BPF_OBJ_NAME_LEN);
707+
memset(dst, 0, size);
707708
/* Copy all isalnum(), '_' and '.' chars. */
708709
while (src < end && *src) {
709710
if (!isalnum(*src) &&
@@ -712,11 +713,11 @@ static int bpf_obj_name_cpy(char *dst, const char *src)
712713
*dst++ = *src++;
713714
}
714715

715-
/* No '\0' found in BPF_OBJ_NAME_LEN number of bytes */
716+
/* No '\0' found in "size" number of bytes */
716717
if (src == end)
717718
return -EINVAL;
718719

719-
return 0;
720+
return src - orig_src;
720721
}
721722

722723
int map_check_no_btf(const struct bpf_map *map,
@@ -810,8 +811,9 @@ static int map_create(union bpf_attr *attr)
810811
if (IS_ERR(map))
811812
return PTR_ERR(map);
812813

813-
err = bpf_obj_name_cpy(map->name, attr->map_name);
814-
if (err)
814+
err = bpf_obj_name_cpy(map->name, attr->map_name,
815+
sizeof(attr->map_name));
816+
if (err < 0)
815817
goto free_map;
816818

817819
atomic64_set(&map->refcnt, 1);
@@ -2098,8 +2100,9 @@ static int bpf_prog_load(union bpf_attr *attr, union bpf_attr __user *uattr)
20982100
goto free_prog;
20992101

21002102
prog->aux->load_time = ktime_get_boottime_ns();
2101-
err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name);
2102-
if (err)
2103+
err = bpf_obj_name_cpy(prog->aux->name, attr->prog_name,
2104+
sizeof(attr->prog_name));
2105+
if (err < 0)
21032106
goto free_prog;
21042107

21052108
/* run eBPF verifier */
@@ -2792,7 +2795,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
27922795
union bpf_attr __user *uattr)
27932796
{
27942797
struct bpf_prog_info __user *uinfo = u64_to_user_ptr(attr->info.info);
2795-
struct bpf_prog_info info = {};
2798+
struct bpf_prog_info info;
27962799
u32 info_len = attr->info.info_len;
27972800
struct bpf_prog_stats stats;
27982801
char __user *uinsns;
@@ -2804,6 +2807,7 @@ static int bpf_prog_get_info_by_fd(struct bpf_prog *prog,
28042807
return err;
28052808
info_len = min_t(u32, sizeof(info), info_len);
28062809

2810+
memset(&info, 0, sizeof(info));
28072811
if (copy_from_user(&info, uinfo, info_len))
28082812
return -EFAULT;
28092813

@@ -3067,7 +3071,7 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
30673071
union bpf_attr __user *uattr)
30683072
{
30693073
struct bpf_map_info __user *uinfo = u64_to_user_ptr(attr->info.info);
3070-
struct bpf_map_info info = {};
3074+
struct bpf_map_info info;
30713075
u32 info_len = attr->info.info_len;
30723076
int err;
30733077

@@ -3076,6 +3080,7 @@ static int bpf_map_get_info_by_fd(struct bpf_map *map,
30763080
return err;
30773081
info_len = min_t(u32, sizeof(info), info_len);
30783082

3083+
memset(&info, 0, sizeof(info));
30793084
info.type = map->map_type;
30803085
info.id = map->id;
30813086
info.key_size = map->key_size;
@@ -3359,7 +3364,7 @@ static int bpf_map_do_batch(const union bpf_attr *attr,
33593364

33603365
SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, size)
33613366
{
3362-
union bpf_attr attr = {};
3367+
union bpf_attr attr;
33633368
int err;
33643369

33653370
if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN))
@@ -3371,6 +3376,7 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf_attr __user *, uattr, unsigned int, siz
33713376
size = min_t(u32, size, sizeof(attr));
33723377

33733378
/* copy attributes from user space, may be less than sizeof(bpf_attr) */
3379+
memset(&attr, 0, sizeof(attr));
33743380
if (copy_from_user(&attr, uattr, size) != 0)
33753381
return -EFAULT;
33763382

net/ipv4/bpf_tcp_ca.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,6 @@ static int bpf_tcp_ca_init_member(const struct btf_type *t,
184184
{
185185
const struct tcp_congestion_ops *utcp_ca;
186186
struct tcp_congestion_ops *tcp_ca;
187-
size_t tcp_ca_name_len;
188187
int prog_fd;
189188
u32 moff;
190189

@@ -199,13 +198,11 @@ static int bpf_tcp_ca_init_member(const struct btf_type *t,
199198
tcp_ca->flags = utcp_ca->flags;
200199
return 1;
201200
case offsetof(struct tcp_congestion_ops, name):
202-
tcp_ca_name_len = strnlen(utcp_ca->name, sizeof(utcp_ca->name));
203-
if (!tcp_ca_name_len ||
204-
tcp_ca_name_len == sizeof(utcp_ca->name))
201+
if (bpf_obj_name_cpy(tcp_ca->name, utcp_ca->name,
202+
sizeof(tcp_ca->name)) <= 0)
205203
return -EINVAL;
206204
if (tcp_ca_find(utcp_ca->name))
207205
return -EEXIST;
208-
memcpy(tcp_ca->name, utcp_ca->name, sizeof(tcp_ca->name));
209206
return 1;
210207
}
211208

0 commit comments

Comments
 (0)