Skip to content

Commit 986e54c

Browse files
committed
Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf
Daniel Borkmann says: ==================== pull-request: bpf 2018-04-21 The following pull-request contains BPF updates for your *net* tree. The main changes are: 1) Fix a deadlock between mm->mmap_sem and bpf_event_mutex when one task is detaching a BPF prog via perf_event_detach_bpf_prog() and another one dumping through bpf_prog_array_copy_info(). For the latter we move the copy_to_user() out of the bpf_event_mutex lock to fix it, from Yonghong. 2) Fix test_sock and test_sock_addr.sh failures. The former was hitting rlimit issues and the latter required ping to specify the address family, from Yonghong. 3) Remove a dead check in sockmap's sock_map_alloc(), from Jann. 4) Add generated files to BPF kselftests gitignore that were previously missed, from Anders. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 660e309 + 6ab690a commit 986e54c

File tree

8 files changed

+59
-27
lines changed

8 files changed

+59
-27
lines changed

include/linux/bpf.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,8 +339,8 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
339339
void bpf_prog_array_delete_safe(struct bpf_prog_array __rcu *progs,
340340
struct bpf_prog *old_prog);
341341
int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
342-
__u32 __user *prog_ids, u32 request_cnt,
343-
__u32 __user *prog_cnt);
342+
u32 *prog_ids, u32 request_cnt,
343+
u32 *prog_cnt);
344344
int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
345345
struct bpf_prog *exclude_prog,
346346
struct bpf_prog *include_prog,

kernel/bpf/core.c

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1572,13 +1572,32 @@ int bpf_prog_array_length(struct bpf_prog_array __rcu *progs)
15721572
return cnt;
15731573
}
15741574

1575+
static bool bpf_prog_array_copy_core(struct bpf_prog **prog,
1576+
u32 *prog_ids,
1577+
u32 request_cnt)
1578+
{
1579+
int i = 0;
1580+
1581+
for (; *prog; prog++) {
1582+
if (*prog == &dummy_bpf_prog.prog)
1583+
continue;
1584+
prog_ids[i] = (*prog)->aux->id;
1585+
if (++i == request_cnt) {
1586+
prog++;
1587+
break;
1588+
}
1589+
}
1590+
1591+
return !!(*prog);
1592+
}
1593+
15751594
int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
15761595
__u32 __user *prog_ids, u32 cnt)
15771596
{
15781597
struct bpf_prog **prog;
15791598
unsigned long err = 0;
1580-
u32 i = 0, *ids;
15811599
bool nospc;
1600+
u32 *ids;
15821601

15831602
/* users of this function are doing:
15841603
* cnt = bpf_prog_array_length();
@@ -1595,16 +1614,7 @@ int bpf_prog_array_copy_to_user(struct bpf_prog_array __rcu *progs,
15951614
return -ENOMEM;
15961615
rcu_read_lock();
15971616
prog = rcu_dereference(progs)->progs;
1598-
for (; *prog; prog++) {
1599-
if (*prog == &dummy_bpf_prog.prog)
1600-
continue;
1601-
ids[i] = (*prog)->aux->id;
1602-
if (++i == cnt) {
1603-
prog++;
1604-
break;
1605-
}
1606-
}
1607-
nospc = !!(*prog);
1617+
nospc = bpf_prog_array_copy_core(prog, ids, cnt);
16081618
rcu_read_unlock();
16091619
err = copy_to_user(prog_ids, ids, cnt * sizeof(u32));
16101620
kfree(ids);
@@ -1683,22 +1693,25 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array,
16831693
}
16841694

16851695
int bpf_prog_array_copy_info(struct bpf_prog_array __rcu *array,
1686-
__u32 __user *prog_ids, u32 request_cnt,
1687-
__u32 __user *prog_cnt)
1696+
u32 *prog_ids, u32 request_cnt,
1697+
u32 *prog_cnt)
16881698
{
1699+
struct bpf_prog **prog;
16891700
u32 cnt = 0;
16901701

16911702
if (array)
16921703
cnt = bpf_prog_array_length(array);
16931704

1694-
if (copy_to_user(prog_cnt, &cnt, sizeof(cnt)))
1695-
return -EFAULT;
1705+
*prog_cnt = cnt;
16961706

16971707
/* return early if user requested only program count or nothing to copy */
16981708
if (!request_cnt || !cnt)
16991709
return 0;
17001710

1701-
return bpf_prog_array_copy_to_user(array, prog_ids, request_cnt);
1711+
/* this function is called under trace/bpf_trace.c: bpf_event_mutex */
1712+
prog = rcu_dereference_check(array, 1)->progs;
1713+
return bpf_prog_array_copy_core(prog, prog_ids, request_cnt) ? -ENOSPC
1714+
: 0;
17021715
}
17031716

17041717
static void bpf_prog_free_deferred(struct work_struct *work)

kernel/bpf/sockmap.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,9 +1442,6 @@ static struct bpf_map *sock_map_alloc(union bpf_attr *attr)
14421442
attr->value_size != 4 || attr->map_flags & ~SOCK_CREATE_FLAG_MASK)
14431443
return ERR_PTR(-EINVAL);
14441444

1445-
if (attr->value_size > KMALLOC_MAX_SIZE)
1446-
return ERR_PTR(-E2BIG);
1447-
14481445
err = bpf_tcp_ulp_register();
14491446
if (err && err != -EEXIST)
14501447
return ERR_PTR(err);

kernel/trace/bpf_trace.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -977,6 +977,7 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)
977977
{
978978
struct perf_event_query_bpf __user *uquery = info;
979979
struct perf_event_query_bpf query = {};
980+
u32 *ids, prog_cnt, ids_len;
980981
int ret;
981982

982983
if (!capable(CAP_SYS_ADMIN))
@@ -985,16 +986,32 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info)
985986
return -EINVAL;
986987
if (copy_from_user(&query, uquery, sizeof(query)))
987988
return -EFAULT;
988-
if (query.ids_len > BPF_TRACE_MAX_PROGS)
989+
990+
ids_len = query.ids_len;
991+
if (ids_len > BPF_TRACE_MAX_PROGS)
989992
return -E2BIG;
993+
ids = kcalloc(ids_len, sizeof(u32), GFP_USER | __GFP_NOWARN);
994+
if (!ids)
995+
return -ENOMEM;
996+
/*
997+
* The above kcalloc returns ZERO_SIZE_PTR when ids_len = 0, which
998+
* is required when user only wants to check for uquery->prog_cnt.
999+
* There is no need to check for it since the case is handled
1000+
* gracefully in bpf_prog_array_copy_info.
1001+
*/
9901002

9911003
mutex_lock(&bpf_event_mutex);
9921004
ret = bpf_prog_array_copy_info(event->tp_event->prog_array,
993-
uquery->ids,
994-
query.ids_len,
995-
&uquery->prog_cnt);
1005+
ids,
1006+
ids_len,
1007+
&prog_cnt);
9961008
mutex_unlock(&bpf_event_mutex);
9971009

1010+
if (copy_to_user(&uquery->prog_cnt, &prog_cnt, sizeof(prog_cnt)) ||
1011+
copy_to_user(uquery->ids, ids, ids_len * sizeof(u32)))
1012+
ret = -EFAULT;
1013+
1014+
kfree(ids);
9981015
return ret;
9991016
}
10001017

tools/testing/selftests/bpf/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@ test_tcpbpf_user
1212
test_verifier_log
1313
feature
1414
test_libbpf_open
15+
test_sock
16+
test_sock_addr
17+
urandom_read

tools/testing/selftests/bpf/test_sock.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <bpf/bpf.h>
1414

1515
#include "cgroup_helpers.h"
16+
#include "bpf_rlimit.h"
1617

1718
#ifndef ARRAY_SIZE
1819
# define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))

tools/testing/selftests/bpf/test_sock_addr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <bpf/libbpf.h>
1616

1717
#include "cgroup_helpers.h"
18+
#include "bpf_rlimit.h"
1819

1920
#define CG_PATH "/foo"
2021
#define CONNECT4_PROG_PATH "./connect4_prog.o"

tools/testing/selftests/bpf/test_sock_addr.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ set -eu
44

55
ping_once()
66
{
7-
ping -q -c 1 -W 1 ${1%%/*} >/dev/null 2>&1
7+
ping -${1} -q -c 1 -W 1 ${2%%/*} >/dev/null 2>&1
88
}
99

1010
wait_for_ip()
@@ -13,7 +13,7 @@ wait_for_ip()
1313
echo -n "Wait for testing IPv4/IPv6 to become available "
1414
for _i in $(seq ${MAX_PING_TRIES}); do
1515
echo -n "."
16-
if ping_once ${TEST_IPv4} && ping_once ${TEST_IPv6}; then
16+
if ping_once 4 ${TEST_IPv4} && ping_once 6 ${TEST_IPv6}; then
1717
echo " OK"
1818
return
1919
fi

0 commit comments

Comments
 (0)