* [PATCH net 2/3] ipv6: tcp: provide sk->sk_priority to ctl packets
From: Eric Dumazet @ 2019-09-24 15:01 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, Eric Dumazet, Eric Dumazet
In-Reply-To: <20190924150116.199028-1-edumazet@google.com>
We can populate skb->priority for some ctl packets
instead of always using zero.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
net/ipv6/tcp_ipv6.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 806064c2886777ad37a1f0b8406aa8bee7945723..5f557bf27da2ba6bcc74034a53a3f76a99fdf9f4 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -804,7 +804,7 @@ static const struct tcp_request_sock_ops tcp_request_sock_ipv6_ops = {
static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32 seq,
u32 ack, u32 win, u32 tsval, u32 tsecr,
int oif, struct tcp_md5sig_key *key, int rst,
- u8 tclass, __be32 label)
+ u8 tclass, __be32 label, u32 priority)
{
const struct tcphdr *th = tcp_hdr(skb);
struct tcphdr *t1;
@@ -909,7 +909,7 @@ static void tcp_v6_send_response(const struct sock *sk, struct sk_buff *skb, u32
if (!IS_ERR(dst)) {
skb_dst_set(buff, dst);
ip6_xmit(ctl_sk, buff, &fl6, fl6.flowi6_mark, NULL, tclass,
- 0);
+ priority);
TCP_INC_STATS(net, TCP_MIB_OUTSEGS);
if (rst)
TCP_INC_STATS(net, TCP_MIB_OUTRSTS);
@@ -932,6 +932,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
struct sock *sk1 = NULL;
#endif
__be32 label = 0;
+ u32 priority = 0;
struct net *net;
int oif = 0;
@@ -992,6 +993,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
trace_tcp_send_reset(sk, skb);
if (np->repflow)
label = ip6_flowlabel(ipv6h);
+ priority = sk->sk_priority;
}
if (sk->sk_state == TCP_TIME_WAIT)
label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel);
@@ -1001,7 +1003,7 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
}
tcp_v6_send_response(sk, skb, seq, ack_seq, 0, 0, 0, oif, key, 1, 0,
- label);
+ label, priority);
#ifdef CONFIG_TCP_MD5SIG
out:
@@ -1012,10 +1014,10 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
static void tcp_v6_send_ack(const struct sock *sk, struct sk_buff *skb, u32 seq,
u32 ack, u32 win, u32 tsval, u32 tsecr, int oif,
struct tcp_md5sig_key *key, u8 tclass,
- __be32 label)
+ __be32 label, u32 priority)
{
tcp_v6_send_response(sk, skb, seq, ack, win, tsval, tsecr, oif, key, 0,
- tclass, label);
+ tclass, label, priority);
}
static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
@@ -1027,7 +1029,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
tcp_time_stamp_raw() + tcptw->tw_ts_offset,
tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw),
- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel));
+ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), 0);
inet_twsk_put(tw);
}
@@ -1050,7 +1052,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
req->ts_recent, sk->sk_bound_dev_if,
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr),
- 0, 0);
+ 0, 0, sk->sk_priority);
}
--
2.23.0.351.gc4317032e6-goog
^ permalink raw reply related
* [PATCH net 3/3] tcp: honor SO_PRIORITY in TIME_WAIT state
From: Eric Dumazet @ 2019-09-24 15:01 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, Eric Dumazet, Eric Dumazet
In-Reply-To: <20190924150116.199028-1-edumazet@google.com>
ctl packets sent on behalf of TIME_WAIT sockets currently
have a zero skb->priority, which can cause various problems.
In this patch we :
- add a tw_priority field in struct inet_timewait_sock.
- populate it from sk->sk_priority when a TIME_WAIT is created.
- For IPv4, change ip_send_unicast_reply() and its two
callers to propagate tw_priority correctly.
ip_send_unicast_reply() no longer changes sk->sk_priority.
- For IPv6, make sure TIME_WAIT sockets pass their tw_priority
field to tcp_v6_send_response() and tcp_v6_send_ack().
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/inet_timewait_sock.h | 1 +
net/ipv4/ip_output.c | 1 -
net/ipv4/tcp_ipv4.c | 4 ++++
net/ipv4/tcp_minisocks.c | 1 +
net/ipv6/tcp_ipv6.c | 6 ++++--
5 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index aef38c140014600dbf88b1d664bad1b0adf63668..dfd919b3119e8efcbc436a67e3e6fbd02091db10 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -71,6 +71,7 @@ struct inet_timewait_sock {
tw_pad : 2, /* 2 bits hole */
tw_tos : 8;
u32 tw_txhash;
+ u32 tw_priority;
struct timer_list tw_timer;
struct inet_bind_bucket *tw_tb;
};
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index a77c3a4c24de40ff6bf3fa9da9a018457139e2b5..28fca408812c5576fc4ea957c1c4dec97ec8faf3 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1694,7 +1694,6 @@ void ip_send_unicast_reply(struct sock *sk, struct sk_buff *skb,
inet_sk(sk)->tos = arg->tos;
- sk->sk_priority = skb->priority;
sk->sk_protocol = ip_hdr(skb)->protocol;
sk->sk_bound_dev_if = arg->bound_dev_if;
sk->sk_sndbuf = sysctl_wmem_default;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fd394ad179a008085b4e87215290f243ea1993b6..2ee45e3755e92e60b5e1810e2f68205221b8308d 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -771,6 +771,8 @@ static void tcp_v4_send_reset(const struct sock *sk, struct sk_buff *skb)
if (sk) {
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
inet_twsk(sk)->tw_mark : sk->sk_mark;
+ ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
+ inet_twsk(sk)->tw_priority : sk->sk_priority;
transmit_time = tcp_transmit_time(sk);
}
ip_send_unicast_reply(ctl_sk,
@@ -866,6 +868,8 @@ static void tcp_v4_send_ack(const struct sock *sk,
ctl_sk = this_cpu_read(*net->ipv4.tcp_sk);
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
inet_twsk(sk)->tw_mark : sk->sk_mark;
+ ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
+ inet_twsk(sk)->tw_priority : sk->sk_priority;
transmit_time = tcp_transmit_time(sk);
ip_send_unicast_reply(ctl_sk,
skb, &TCP_SKB_CB(skb)->header.h4.opt,
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
index 8bcaf2586b6892b52fc3b25545017ec21afb0bde..bb140a5db8c066e57f1018fd47bccd4628def642 100644
--- a/net/ipv4/tcp_minisocks.c
+++ b/net/ipv4/tcp_minisocks.c
@@ -266,6 +266,7 @@ void tcp_time_wait(struct sock *sk, int state, int timeo)
tw->tw_transparent = inet->transparent;
tw->tw_mark = sk->sk_mark;
+ tw->tw_priority = sk->sk_priority;
tw->tw_rcv_wscale = tp->rx_opt.rcv_wscale;
tcptw->tw_rcv_nxt = tp->rcv_nxt;
tcptw->tw_snd_nxt = tp->snd_nxt;
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 5f557bf27da2ba6bcc74034a53a3f76a99fdf9f4..e3d9f4559c99f252eba448845cce434bc53f3fd8 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -995,8 +995,10 @@ static void tcp_v6_send_reset(const struct sock *sk, struct sk_buff *skb)
label = ip6_flowlabel(ipv6h);
priority = sk->sk_priority;
}
- if (sk->sk_state == TCP_TIME_WAIT)
+ if (sk->sk_state == TCP_TIME_WAIT) {
label = cpu_to_be32(inet_twsk(sk)->tw_flowlabel);
+ priority = inet_twsk(sk)->tw_priority;
+ }
} else {
if (net->ipv6.sysctl.flowlabel_reflect & FLOWLABEL_REFLECT_TCP_RESET)
label = ip6_flowlabel(ipv6h);
@@ -1029,7 +1031,7 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
tcp_time_stamp_raw() + tcptw->tw_ts_offset,
tcptw->tw_ts_recent, tw->tw_bound_dev_if, tcp_twsk_md5_key(tcptw),
- tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), 0);
+ tw->tw_tclass, cpu_to_be32(tw->tw_flowlabel), tw->tw_priority);
inet_twsk_put(tw);
}
--
2.23.0.351.gc4317032e6-goog
^ permalink raw reply related
* [PATCH net 0/3] tcp: provide correct skb->priority
From: Eric Dumazet @ 2019-09-24 15:01 UTC (permalink / raw)
To: David S . Miller; +Cc: netdev, Eric Dumazet, Eric Dumazet
SO_PRIORITY socket option requests TCP egress packets
to contain a user provided value.
TCP manages to send most packets with the requested values,
notably for TCP_ESTABLISHED state, but fails to do so for
few packets.
These packets are control packets sent on behalf
of SYN_RECV or TIME_WAIT states.
Note that to test this with packetdrill, it is a bit
of a hassle, since packetdrill can not verify priority
of egress packets, other than indirect observations,
using for example sch_prio on its tunnel device.
The bad skb priorities cause problems for GCP,
as this field is one of the keys used in routing.
Eric Dumazet (3):
ipv6: add priority parameter to ip6_xmit()
ipv6: tcp: provide sk->sk_priority to ctl packets
tcp: honor SO_PRIORITY in TIME_WAIT state
include/net/inet_timewait_sock.h | 1 +
include/net/ipv6.h | 2 +-
net/dccp/ipv6.c | 5 +++--
net/ipv4/ip_output.c | 1 -
net/ipv4/tcp_ipv4.c | 4 ++++
net/ipv4/tcp_minisocks.c | 1 +
net/ipv6/inet6_connection_sock.c | 2 +-
net/ipv6/ip6_output.c | 4 ++--
net/ipv6/tcp_ipv6.c | 24 +++++++++++++++---------
net/sctp/ipv6.c | 2 +-
10 files changed, 29 insertions(+), 17 deletions(-)
--
2.23.0.351.gc4317032e6-goog
^ permalink raw reply
* Re: [PATCH net] ppp: Fix memory leak in ppp_write
From: Guillaume Nault @ 2019-09-24 15:06 UTC (permalink / raw)
To: Takeshi Misawa; +Cc: Paul Mackerras, netdev
In-Reply-To: <20190922074531.GA1450@DESKTOP>
On Sun, Sep 22, 2019 at 04:45:31PM +0900, Takeshi Misawa wrote:
> When ppp is closing, __ppp_xmit_process() failed to enqueue skb
> and skb allocated in ppp_write() is leaked.
>
> syzbot reported :
> BUG: memory leak
> unreferenced object 0xffff88812a17bc00 (size 224):
> comm "syz-executor673", pid 6952, jiffies 4294942888 (age 13.040s)
> hex dump (first 32 bytes):
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
> backtrace:
> [<00000000d110fff9>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline]
> [<00000000d110fff9>] slab_post_alloc_hook mm/slab.h:522 [inline]
> [<00000000d110fff9>] slab_alloc_node mm/slab.c:3262 [inline]
> [<00000000d110fff9>] kmem_cache_alloc_node+0x163/0x2f0 mm/slab.c:3574
> [<000000002d616113>] __alloc_skb+0x6e/0x210 net/core/skbuff.c:197
> [<000000000167fc45>] alloc_skb include/linux/skbuff.h:1055 [inline]
> [<000000000167fc45>] ppp_write+0x48/0x120 drivers/net/ppp/ppp_generic.c:502
> [<000000009ab42c0b>] __vfs_write+0x43/0xa0 fs/read_write.c:494
> [<00000000086b2e22>] vfs_write fs/read_write.c:558 [inline]
> [<00000000086b2e22>] vfs_write+0xee/0x210 fs/read_write.c:542
> [<00000000a2b70ef9>] ksys_write+0x7c/0x130 fs/read_write.c:611
> [<00000000ce5e0fdd>] __do_sys_write fs/read_write.c:623 [inline]
> [<00000000ce5e0fdd>] __se_sys_write fs/read_write.c:620 [inline]
> [<00000000ce5e0fdd>] __x64_sys_write+0x1e/0x30 fs/read_write.c:620
> [<00000000d9d7b370>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:296
> [<0000000006e6d506>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
>
> Fix this by freeing skb, if ppp is closing.
>
> Fixes: 6d066734e9f0 ("ppp: avoid loop in xmit recursion detection code")
> Reported-and-tested-by: syzbot+d9c8bf24e56416d7ce2c@syzkaller.appspotmail.com
> Signed-off-by: Takeshi Misawa <jeliantsurux@gmail.com>
> ---
> Dear Guillaume Nault, Paul Mackerras
>
> syzbot reported memory leak in net/ppp.
> - memory leak in ppp_write
>
> I send a patch that passed syzbot reproducer test.
> Please consider this memory leak and patch.
>
> Regards.
> ---
> drivers/net/ppp/ppp_generic.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c
> index a30e41a56085..9a1b006904a7 100644
> --- a/drivers/net/ppp/ppp_generic.c
> +++ b/drivers/net/ppp/ppp_generic.c
> @@ -1415,6 +1415,8 @@ static void __ppp_xmit_process(struct ppp *ppp, struct sk_buff *skb)
> netif_wake_queue(ppp->dev);
> else
> netif_stop_queue(ppp->dev);
> + } else {
> + kfree_skb(skb);
> }
> ppp_xmit_unlock(ppp);
> }
Thanks a lot Takeshi!
Reviewed-by: Guillaume Nault <gnault@redhat.com>
Tested-by: Guillaume Nault <gnault@redhat.com>
^ permalink raw reply
* [PATCH V11 0/4] BPF: New helper to obtain namespace data from current task
From: Carlos Neira @ 2019-09-24 15:20 UTC (permalink / raw)
To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos
Currently bpf_get_current_pid_tgid(), is used to do pid filtering in bcc's
scripts but this helper returns the pid as seen by the root namespace which is
fine when a bcc script is not executed inside a container.
When the process of interest is inside a container, pid filtering will not work
if bpf_get_current_pid_tgid() is used.
This helper addresses this limitation returning the pid as it's seen by the current
namespace where the script is executing.
In the future different pid_ns files may belong to different devices, according to the
discussion between Eric Biederman and Yonghong in 2017 Linux plumbers conference.
To address that situation the helper requires inum and dev_t from /proc/self/ns/pid.
This helper has the same use cases as bpf_get_current_pid_tgid() as it can be
used to do pid filtering even inside a container.
Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
Carlos Neira (4):
fs/nsfs.c: added ns_match
bpf: added new helper bpf_get_ns_current_pid_tgid
tools: Added bpf_get_ns_current_pid_tgid helper
tools/testing/selftests/bpf: Add self-tests for new helper. self tests
added for new helper
fs/nsfs.c | 8 +
include/linux/bpf.h | 1 +
include/linux/proc_ns.h | 2 +
include/uapi/linux/bpf.h | 18 ++-
kernel/bpf/core.c | 1 +
kernel/bpf/helpers.c | 32 ++++
kernel/trace/bpf_trace.c | 2 +
tools/include/uapi/linux/bpf.h | 18 ++-
tools/testing/selftests/bpf/Makefile | 2 +-
tools/testing/selftests/bpf/bpf_helpers.h | 3 +
.../selftests/bpf/progs/test_pidns_kern.c | 71 ++++++++
tools/testing/selftests/bpf/test_pidns.c | 152 ++++++++++++++++++
12 files changed, 307 insertions(+), 3 deletions(-)
create mode 100644 tools/testing/selftests/bpf/progs/test_pidns_kern.c
create mode 100644 tools/testing/selftests/bpf/test_pidns.c
--
2.20.1
^ permalink raw reply
* [PATCH bpf-next v11 1/4] fs/nsfs.c: added ns_match
From: Carlos Neira @ 2019-09-24 15:20 UTC (permalink / raw)
To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos
In-Reply-To: <20190924152005.4659-1-cneirabustos@gmail.com>
ns_match returns true if the namespace inode and dev_t matches the ones
provided by the caller.
Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
---
fs/nsfs.c | 8 ++++++++
include/linux/proc_ns.h | 2 ++
2 files changed, 10 insertions(+)
diff --git a/fs/nsfs.c b/fs/nsfs.c
index a0431642c6b5..256f6295d33d 100644
--- a/fs/nsfs.c
+++ b/fs/nsfs.c
@@ -245,6 +245,14 @@ struct file *proc_ns_fget(int fd)
return ERR_PTR(-EINVAL);
}
+/* Returns true if current namespace matches dev/ino.
+ */
+bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino)
+{
+ return ((ns->inum == ino) && (nsfs_mnt->mnt_sb->s_dev == dev));
+}
+
+
static int nsfs_show_path(struct seq_file *seq, struct dentry *dentry)
{
struct inode *inode = d_inode(dentry);
diff --git a/include/linux/proc_ns.h b/include/linux/proc_ns.h
index d31cb6215905..1da9f33489f3 100644
--- a/include/linux/proc_ns.h
+++ b/include/linux/proc_ns.h
@@ -82,6 +82,8 @@ typedef struct ns_common *ns_get_path_helper_t(void *);
extern void *ns_get_path_cb(struct path *path, ns_get_path_helper_t ns_get_cb,
void *private_data);
+extern bool ns_match(const struct ns_common *ns, dev_t dev, ino_t ino);
+
extern int ns_get_name(char *buf, size_t size, struct task_struct *task,
const struct proc_ns_operations *ns_ops);
extern void nsfs_init(void);
--
2.20.1
^ permalink raw reply related
* [PATCH bpf-next v11 2/4] bpf: added new helper bpf_get_ns_current_pid_tgid
From: Carlos Neira @ 2019-09-24 15:20 UTC (permalink / raw)
To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos
In-Reply-To: <20190924152005.4659-1-cneirabustos@gmail.com>
New bpf helper bpf_get_ns_current_pid_tgid,
This helper will return pid and tgid from current task
which namespace matches dev_t and inode number provided,
this will allows us to instrument a process inside a container.
Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
---
include/linux/bpf.h | 1 +
include/uapi/linux/bpf.h | 18 +++++++++++++++++-
kernel/bpf/core.c | 1 +
kernel/bpf/helpers.c | 32 ++++++++++++++++++++++++++++++++
kernel/trace/bpf_trace.c | 2 ++
5 files changed, 53 insertions(+), 1 deletion(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 5b9d22338606..231001475504 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -1055,6 +1055,7 @@ extern const struct bpf_func_proto bpf_get_local_storage_proto;
extern const struct bpf_func_proto bpf_strtol_proto;
extern const struct bpf_func_proto bpf_strtoul_proto;
extern const struct bpf_func_proto bpf_tcp_sock_proto;
+extern const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto;
/* Shared helpers among cBPF and eBPF. */
void bpf_user_rnd_init_once(void);
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 77c6be96d676..9272dc8fb08c 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2750,6 +2750,21 @@ union bpf_attr {
* **-EOPNOTSUPP** kernel configuration does not enable SYN cookies
*
* **-EPROTONOSUPPORT** IP packet version is not 4 or 6
+ *
+ * int bpf_get_ns_current_pid_tgid(u32 dev, u64 inum)
+ * Return
+ * A 64-bit integer containing the current tgid and pid from current task
+ * which namespace inode and dev_t matches , and is create as such:
+ * *current_task*\ **->tgid << 32 \|**
+ * *current_task*\ **->pid**.
+ *
+ * On failure, the returned value is one of the following:
+ *
+ * **-EINVAL** if dev and inum supplied don't match dev_t and inode number
+ * with nsfs of current task.
+ *
+ * **-ENOENT** if /proc/self/ns does not exists.
+ *
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2862,7 +2877,8 @@ union bpf_attr {
FN(sk_storage_get), \
FN(sk_storage_delete), \
FN(send_signal), \
- FN(tcp_gen_syncookie),
+ FN(tcp_gen_syncookie), \
+ FN(get_ns_current_pid_tgid),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
diff --git a/kernel/bpf/core.c b/kernel/bpf/core.c
index 66088a9e9b9e..b2fd5358f472 100644
--- a/kernel/bpf/core.c
+++ b/kernel/bpf/core.c
@@ -2042,6 +2042,7 @@ const struct bpf_func_proto bpf_get_current_uid_gid_proto __weak;
const struct bpf_func_proto bpf_get_current_comm_proto __weak;
const struct bpf_func_proto bpf_get_current_cgroup_id_proto __weak;
const struct bpf_func_proto bpf_get_local_storage_proto __weak;
+const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto __weak;
const struct bpf_func_proto * __weak bpf_get_trace_printk_proto(void)
{
diff --git a/kernel/bpf/helpers.c b/kernel/bpf/helpers.c
index 5e28718928ca..81a716eae7ed 100644
--- a/kernel/bpf/helpers.c
+++ b/kernel/bpf/helpers.c
@@ -11,6 +11,8 @@
#include <linux/uidgid.h>
#include <linux/filter.h>
#include <linux/ctype.h>
+#include <linux/pid_namespace.h>
+#include <linux/proc_ns.h>
#include "../../lib/kstrtox.h"
@@ -487,3 +489,33 @@ const struct bpf_func_proto bpf_strtoul_proto = {
.arg4_type = ARG_PTR_TO_LONG,
};
#endif
+
+BPF_CALL_2(bpf_get_ns_current_pid_tgid, u32, dev, u64, inum)
+{
+ struct task_struct *task = current;
+ struct pid_namespace *pidns;
+ pid_t pid, tgid;
+
+ if (unlikely(!task))
+ return -EINVAL;
+
+ pidns = task_active_pid_ns(task);
+ if (unlikely(!pidns))
+ return -ENOENT;
+
+ if (!ns_match(&pidns->ns, (dev_t)dev, inum))
+ return -EINVAL;
+
+ pid = task_pid_nr_ns(task, pidns);
+ tgid = task_tgid_nr_ns(task, pidns);
+
+ return (u64) tgid << 32 | pid;
+}
+
+const struct bpf_func_proto bpf_get_ns_current_pid_tgid_proto = {
+ .func = bpf_get_ns_current_pid_tgid,
+ .gpl_only = false,
+ .ret_type = RET_INTEGER,
+ .arg1_type = ARG_ANYTHING,
+ .arg2_type = ARG_ANYTHING,
+};
diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c
index ca1255d14576..1d34f1013e78 100644
--- a/kernel/trace/bpf_trace.c
+++ b/kernel/trace/bpf_trace.c
@@ -709,6 +709,8 @@ tracing_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
#endif
case BPF_FUNC_send_signal:
return &bpf_send_signal_proto;
+ case BPF_FUNC_get_ns_current_pid_tgid:
+ return &bpf_get_ns_current_pid_tgid_proto;
default:
return NULL;
}
--
2.20.1
^ permalink raw reply related
* [PATCH bpf-next v11 3/4] tools: Added bpf_get_ns_current_pid_tgid helper
From: Carlos Neira @ 2019-09-24 15:20 UTC (permalink / raw)
To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos
In-Reply-To: <20190924152005.4659-1-cneirabustos@gmail.com>
Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
---
tools/include/uapi/linux/bpf.h | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 77c6be96d676..9272dc8fb08c 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2750,6 +2750,21 @@ union bpf_attr {
* **-EOPNOTSUPP** kernel configuration does not enable SYN cookies
*
* **-EPROTONOSUPPORT** IP packet version is not 4 or 6
+ *
+ * int bpf_get_ns_current_pid_tgid(u32 dev, u64 inum)
+ * Return
+ * A 64-bit integer containing the current tgid and pid from current task
+ * which namespace inode and dev_t matches , and is create as such:
+ * *current_task*\ **->tgid << 32 \|**
+ * *current_task*\ **->pid**.
+ *
+ * On failure, the returned value is one of the following:
+ *
+ * **-EINVAL** if dev and inum supplied don't match dev_t and inode number
+ * with nsfs of current task.
+ *
+ * **-ENOENT** if /proc/self/ns does not exists.
+ *
*/
#define __BPF_FUNC_MAPPER(FN) \
FN(unspec), \
@@ -2862,7 +2877,8 @@ union bpf_attr {
FN(sk_storage_get), \
FN(sk_storage_delete), \
FN(send_signal), \
- FN(tcp_gen_syncookie),
+ FN(tcp_gen_syncookie), \
+ FN(get_ns_current_pid_tgid),
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
* function eBPF program intends to call
--
2.20.1
^ permalink raw reply related
* [PATCH bpf-next v11 4/4] tools/testing/selftests/bpf: Add self-tests for new helper.
From: Carlos Neira @ 2019-09-24 15:20 UTC (permalink / raw)
To: netdev; +Cc: yhs, ebiederm, brouer, bpf, cneirabustos
In-Reply-To: <20190924152005.4659-1-cneirabustos@gmail.com>
Self tests added for new helper
Signed-off-by: Carlos Neira <cneirabustos@gmail.com>
---
tools/testing/selftests/bpf/Makefile | 2 +-
tools/testing/selftests/bpf/bpf_helpers.h | 3 +
.../selftests/bpf/progs/test_pidns_kern.c | 71 ++++++++
tools/testing/selftests/bpf/test_pidns.c | 152 ++++++++++++++++++
4 files changed, 227 insertions(+), 1 deletion(-)
create mode 100644 tools/testing/selftests/bpf/progs/test_pidns_kern.c
create mode 100644 tools/testing/selftests/bpf/test_pidns.c
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 7f3196af1ae4..d86b28aa8f44 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -28,7 +28,7 @@ TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test
test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
test_cgroup_storage test_select_reuseport test_section_names \
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl test_hashmap \
- test_btf_dump test_cgroup_attach xdping
+ test_btf_dump test_cgroup_attach xdping test_pidns
BPF_OBJ_FILES = $(patsubst %.c,%.o, $(notdir $(wildcard progs/*.c)))
TEST_GEN_FILES = $(BPF_OBJ_FILES)
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index 6c4930bc6e2e..03d0e15ae29f 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -231,6 +231,9 @@ static int (*bpf_send_signal)(unsigned sig) = (void *)BPF_FUNC_send_signal;
static long long (*bpf_tcp_gen_syncookie)(struct bpf_sock *sk, void *ip,
int ip_len, void *tcp, int tcp_len) =
(void *) BPF_FUNC_tcp_gen_syncookie;
+static int (*bpf_get_ns_current_pid_tgid)(__u32 dev, __u64 inum) =
+ (void *) BPF_FUNC_get_ns_current_pid_tgid;
+
/* llvm builtin functions that eBPF C program may use to
* emit BPF_LD_ABS and BPF_LD_IND instructions
diff --git a/tools/testing/selftests/bpf/progs/test_pidns_kern.c b/tools/testing/selftests/bpf/progs/test_pidns_kern.c
new file mode 100644
index 000000000000..96cb707db3ee
--- /dev/null
+++ b/tools/testing/selftests/bpf/progs/test_pidns_kern.c
@@ -0,0 +1,71 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 Carlos Neira cneirabustos@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#include <linux/bpf.h>
+#include "bpf_helpers.h"
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u64);
+} ns_inum_map SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+} ns_dev_map SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u32);
+} pidmap SEC(".maps");
+
+struct {
+ __uint(type, BPF_MAP_TYPE_ARRAY);
+ __uint(max_entries, 1);
+ __type(key, __u32);
+ __type(value, __u64);
+} ns_pid_map SEC(".maps");
+
+
+
+SEC("tracepoint/syscalls/sys_enter_nanosleep")
+int trace(void *ctx)
+{
+ __u32 key = 0, *expected_pid, *dev;
+ __u64 *val, *inum, nspid;
+ __u32 pid;
+
+ dev = bpf_map_lookup_elem(&ns_dev_map, &key);
+ if (!dev)
+ return 0;
+
+ inum = bpf_map_lookup_elem(&ns_inum_map, &key);
+ if (!inum)
+ return 0;
+
+ nspid = bpf_get_ns_current_pid_tgid(*dev, *inum);
+ expected_pid = bpf_map_lookup_elem(&pidmap, &key);
+
+ if (!expected_pid || *expected_pid != nspid)
+ return 0;
+
+ val = bpf_map_lookup_elem(&ns_pid_map, &key);
+ if (val)
+ *val = nspid;
+
+ return 0;
+}
+
+char _license[] SEC("license") = "GPL";
+__u32 _version SEC("version") = 1;
diff --git a/tools/testing/selftests/bpf/test_pidns.c b/tools/testing/selftests/bpf/test_pidns.c
new file mode 100644
index 000000000000..088f8025f2bf
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_pidns.c
@@ -0,0 +1,152 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018 Carlos Neira cneirabustos@gmail.com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <syscall.h>
+#include <unistd.h>
+#include <linux/perf_event.h>
+#include <sys/ioctl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <linux/bpf.h>
+#include <bpf/bpf.h>
+#include <bpf/libbpf.h>
+
+#include "cgroup_helpers.h"
+#include "bpf_rlimit.h"
+
+#define CHECK(condition, tag, format...) ({ \
+ int __ret = !!(condition); \
+ if (__ret) { \
+ printf("%s:FAIL:%s ", __func__, tag); \
+ printf(format); \
+ } else { \
+ printf("%s:PASS:%s\n", __func__, tag); \
+ } \
+ __ret; \
+})
+
+static int bpf_find_map(const char *test, struct bpf_object *obj,
+ const char *name)
+{
+ struct bpf_map *map;
+
+ map = bpf_object__find_map_by_name(obj, name);
+ if (!map)
+ return -1;
+ return bpf_map__fd(map);
+}
+
+
+int main(int argc, char **argv)
+{
+ int pidmap_fd, ns_inum_map_fd, ns_dev_map_fd, ns_pid_map_fd;
+ const char *probe_name = "syscalls/sys_enter_nanosleep";
+ const char *file = "test_pidns_kern.o";
+ int err, bytes, efd, prog_fd, pmu_fd;
+ struct perf_event_attr attr = {};
+ struct bpf_object *obj;
+ __u32 nspid = 0;
+ __u32 key = 0, pid;
+ int exit_code = 1;
+ struct stat st;
+ char buf[256];
+
+ err = bpf_prog_load(file, BPF_PROG_TYPE_TRACEPOINT, &obj, &prog_fd);
+ if (CHECK(err, "bpf_prog_load", "err %d errno %d\n", err, errno))
+ goto cleanup_cgroup_env;
+
+ ns_dev_map_fd = bpf_find_map(__func__, obj, "ns_dev_map");
+ if (CHECK(ns_dev_map_fd < 0, "bpf_find_map", "err %d errno %d\n",
+ ns_dev_map_fd, errno))
+ goto close_prog;
+
+ ns_inum_map_fd = bpf_find_map(__func__, obj, "ns_inum_map");
+ if (CHECK(ns_inum_map_fd < 0, "bpf_find_map", "err %d errno %d\n",
+ ns_inum_map_fd, errno))
+ goto close_prog;
+
+ ns_pid_map_fd = bpf_find_map(__func__, obj, "ns_pid_map");
+ if (CHECK(ns_pid_map_fd < 0, "bpf_find_map", "err %d errno %d\n",
+ ns_pid_map_fd, errno))
+ goto close_prog;
+
+ pidmap_fd = bpf_find_map(__func__, obj, "pidmap");
+ if (CHECK(pidmap_fd < 0, "bpf_find_map", "err %d errno %d\n",
+ pidmap_fd, errno))
+ goto close_prog;
+
+ pid = getpid();
+ bpf_map_update_elem(pidmap_fd, &key, &pid, 0);
+
+ if (stat("/proc/self/ns/pid", &st))
+ goto close_prog;
+
+ bpf_map_update_elem(ns_inum_map_fd, &key, &st.st_ino, 0);
+ bpf_map_update_elem(ns_dev_map_fd, &key, &st.st_dev, 0);
+
+
+ snprintf(buf, sizeof(buf),
+ "/sys/kernel/debug/tracing/events/%s/id", probe_name);
+ efd = open(buf, O_RDONLY, 0);
+ if (CHECK(efd < 0, "open", "err %d errno %d\n", efd, errno))
+ goto close_prog;
+ bytes = read(efd, buf, sizeof(buf));
+ close(efd);
+ if (CHECK(bytes <= 0 || bytes >= sizeof(buf), "read",
+ "bytes %d errno %d\n", bytes, errno))
+ goto close_prog;
+
+ attr.config = strtol(buf, NULL, 0);
+ attr.type = PERF_TYPE_TRACEPOINT;
+ attr.sample_type = PERF_SAMPLE_RAW;
+ attr.sample_period = 1;
+ attr.wakeup_events = 1;
+
+ pmu_fd = syscall(__NR_perf_event_open, &attr, getpid(), -1, -1, 0);
+ if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd,
+ errno))
+ goto close_prog;
+
+ err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
+ if (CHECK(err, "perf_event_ioc_enable", "err %d errno %d\n", err,
+ errno))
+ goto close_pmu;
+
+ err = ioctl(pmu_fd, PERF_EVENT_IOC_SET_BPF, prog_fd);
+ if (CHECK(err, "perf_event_ioc_set_bpf", "err %d errno %d\n", err,
+ errno))
+ goto close_pmu;
+
+ /* trigger some syscalls */
+ sleep(1);
+
+ err = bpf_map_lookup_elem(ns_pid_map_fd, &key, &nspid);
+ if (CHECK(err, "bpf_map_lookup_elem", "err %d errno %d\n", err, errno))
+ goto close_pmu;
+
+ if (CHECK(nspid != pid, "compare nspid vs pid",
+ "kern nspid %u user pid %u", nspid, pid))
+ goto close_pmu;
+
+ exit_code = 0;
+ printf("%s:PASS\n", argv[0]);
+
+close_pmu:
+ close(pmu_fd);
+close_prog:
+ bpf_object__close(obj);
+cleanup_cgroup_env:
+ return exit_code;
+}
--
2.20.1
^ permalink raw reply related
* Linux 5.4 - bpf test build fails
From: Shuah Khan @ 2019-09-24 15:26 UTC (permalink / raw)
To: Alexei Starovoitov, Daniel Borkmann
Cc: open list:KERNEL SELFTEST FRAMEWORK, bpf, Networking,
David S. Miller
Hi Alexei and Daniel,
bpf test doesn't build on Linux 5.4 mainline. Do you know what's
happening here.
make -C tools/testing/selftests/bpf/
-c progs/test_core_reloc_ptr_as_arr.c -o - || echo "clang failed") | \
llc -march=bpf -mcpu=generic -filetype=obj -o
/mnt/data/lkml/linux_5.4/tools/testing/selftests/bpf/test_core_reloc_ptr_as_arr.o
progs/test_core_reloc_ptr_as_arr.c:25:6: error: use of unknown builtin
'__builtin_preserve_access_index' [-Wimplicit-function-declaration]
if (BPF_CORE_READ(&out->a, &in[2].a))
^
./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
__builtin_preserve_access_index(src))
^
progs/test_core_reloc_ptr_as_arr.c:25:6: warning: incompatible integer to
pointer conversion passing 'int' to parameter of type 'const void *'
[-Wint-conversion]
if (BPF_CORE_READ(&out->a, &in[2].a))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
__builtin_preserve_access_index(src))
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning and 1 error generated.
llc: error: llc: <stdin>:1:1: error: expected top-level entity
clang failed
Also
make TARGETS=bpf kselftest fails as well. Dependency between
tools/lib/bpf and the test. How can we avoid this type of
dependency or resolve it in a way it doesn't result in build
failures?
thanks,
-- Shuah
^ permalink raw reply
* [PATCH net-next] net/rds: Check laddr_check before calling it
From: Ka-Cheong Poon @ 2019-09-24 15:27 UTC (permalink / raw)
To: netdev; +Cc: santosh.shilimkar, davem, rds-devel
In-Reply-To: <1568734158-18021-1-git-send-email-ka-cheong.poon@oracle.com>
In rds_bind(), laddr_check is called without checking if it is NULL or
not. And rs_transport should be reset if rds_add_bound() fails.
Fixes: c5c1a030a7db ("net/rds: Check laddr_check before calling it")
Reported-by: syzbot+fae39afd2101a17ec624@syzkaller.appspotmail.com
Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
---
net/rds/bind.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 20c156a..5b5fb4c 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -244,7 +244,8 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
*/
if (rs->rs_transport) {
trans = rs->rs_transport;
- if (trans->laddr_check(sock_net(sock->sk),
+ if (!trans->laddr_check ||
+ trans->laddr_check(sock_net(sock->sk),
binding_addr, scope_id) != 0) {
ret = -ENOPROTOOPT;
goto out;
@@ -263,6 +264,8 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
sock_set_flag(sk, SOCK_RCU_FREE);
ret = rds_add_bound(rs, binding_addr, &port, scope_id);
+ if (ret)
+ rs->rs_transport = NULL;
out:
release_sock(sk);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH net-next] net/rds: Check laddr_check before calling it
From: Ka-Cheong Poon @ 2019-09-24 15:43 UTC (permalink / raw)
To: netdev; +Cc: santosh.shilimkar, davem, rds-devel
In-Reply-To: <1569338876-12857-1-git-send-email-ka-cheong.poon@oracle.com>
On 9/24/19 11:27 PM, Ka-Cheong Poon wrote:
> In rds_bind(), laddr_check is called without checking if it is NULL or
> not. And rs_transport should be reset if rds_add_bound() fails.
>
> Fixes: c5c1a030a7db ("net/rds: Check laddr_check before calling it")
Oops, wrong Subject. Will re-submit. Sorry about that.
> Reported-by: syzbot+fae39afd2101a17ec624@syzkaller.appspotmail.com
> Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
> Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
> ---
> net/rds/bind.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/net/rds/bind.c b/net/rds/bind.c
> index 20c156a..5b5fb4c 100644
> --- a/net/rds/bind.c
> +++ b/net/rds/bind.c
> @@ -244,7 +244,8 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
> */
> if (rs->rs_transport) {
> trans = rs->rs_transport;
> - if (trans->laddr_check(sock_net(sock->sk),
> + if (!trans->laddr_check ||
> + trans->laddr_check(sock_net(sock->sk),
> binding_addr, scope_id) != 0) {
> ret = -ENOPROTOOPT;
> goto out;
> @@ -263,6 +264,8 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
>
> sock_set_flag(sk, SOCK_RCU_FREE);
> ret = rds_add_bound(rs, binding_addr, &port, scope_id);
> + if (ret)
> + rs->rs_transport = NULL;
>
> out:
> release_sock(sk);
>
--
K. Poon
ka-cheong.poon@oracle.com
^ permalink raw reply
* Re: Linux 5.4 - bpf test build fails
From: Yonghong Song @ 2019-09-24 15:43 UTC (permalink / raw)
To: Shuah Khan, Alexei Starovoitov, Daniel Borkmann
Cc: open list:KERNEL SELFTEST FRAMEWORK, bpf, Networking,
David S. Miller, Andrii Nakryiko
In-Reply-To: <742ecabe-45ce-cf6e-2540-25d6dc23c45f@linuxfoundation.org>
On 9/24/19 8:26 AM, Shuah Khan wrote:
> Hi Alexei and Daniel,
>
> bpf test doesn't build on Linux 5.4 mainline. Do you know what's
> happening here.
>
>
> make -C tools/testing/selftests/bpf/
>
> -c progs/test_core_reloc_ptr_as_arr.c -o - || echo "clang failed") | \
> llc -march=bpf -mcpu=generic -filetype=obj -o
> /mnt/data/lkml/linux_5.4/tools/testing/selftests/bpf/test_core_reloc_ptr_as_arr.o
>
> progs/test_core_reloc_ptr_as_arr.c:25:6: error: use of unknown builtin
> '__builtin_preserve_access_index' [-Wimplicit-function-declaration]
> if (BPF_CORE_READ(&out->a, &in[2].a))
> ^
> ./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
> __builtin_preserve_access_index(src))
> ^
> progs/test_core_reloc_ptr_as_arr.c:25:6: warning: incompatible integer to
> pointer conversion passing 'int' to parameter of type 'const void *'
> [-Wint-conversion]
> if (BPF_CORE_READ(&out->a, &in[2].a))
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
> __builtin_preserve_access_index(src))
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 1 warning and 1 error generated.
> llc: error: llc: <stdin>:1:1: error: expected top-level entity
> clang failed
>
> Also
>
> make TARGETS=bpf kselftest fails as well. Dependency between
> tools/lib/bpf and the test. How can we avoid this type of
> dependency or resolve it in a way it doesn't result in build
> failures?
Thanks, Shuah.
The clang __builtin_preserve_access_index() intrinsic is
introduced in LLVM9 (which just released last week) and
the builtin and other CO-RE features are only supported
in LLVM10 (current development branch) with more bug fixes
and added features.
I think we should do a feature test for llvm version and only
enable these tests when llvm version >= 10.
Andrii, what do you think?
>
> thanks,
> -- Shuah
^ permalink raw reply
* Re: Linux 5.4 - bpf test build fails
From: Shuah Khan @ 2019-09-24 15:48 UTC (permalink / raw)
To: Yonghong Song, Alexei Starovoitov, Daniel Borkmann
Cc: open list:KERNEL SELFTEST FRAMEWORK, bpf, Networking,
David S. Miller, Andrii Nakryiko, skh >> Shuah Khan
In-Reply-To: <0a5bf608-bb15-c116-8e58-7224b6c3b62f@fb.com>
On 9/24/19 9:43 AM, Yonghong Song wrote:
>
>
> On 9/24/19 8:26 AM, Shuah Khan wrote:
>> Hi Alexei and Daniel,
>>
>> bpf test doesn't build on Linux 5.4 mainline. Do you know what's
>> happening here.
>>
>>
>> make -C tools/testing/selftests/bpf/
>>
>> -c progs/test_core_reloc_ptr_as_arr.c -o - || echo "clang failed") | \
>> llc -march=bpf -mcpu=generic -filetype=obj -o
>> /mnt/data/lkml/linux_5.4/tools/testing/selftests/bpf/test_core_reloc_ptr_as_arr.o
>>
>> progs/test_core_reloc_ptr_as_arr.c:25:6: error: use of unknown builtin
>> '__builtin_preserve_access_index' [-Wimplicit-function-declaration]
>> if (BPF_CORE_READ(&out->a, &in[2].a))
>> ^
>> ./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
>> __builtin_preserve_access_index(src))
>> ^
>> progs/test_core_reloc_ptr_as_arr.c:25:6: warning: incompatible integer to
>> pointer conversion passing 'int' to parameter of type 'const void *'
>> [-Wint-conversion]
>> if (BPF_CORE_READ(&out->a, &in[2].a))
>> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> ./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
>> __builtin_preserve_access_index(src))
>> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> 1 warning and 1 error generated.
>> llc: error: llc: <stdin>:1:1: error: expected top-level entity
>> clang failed
>>
>> Also
>>
>> make TARGETS=bpf kselftest fails as well. Dependency between
>> tools/lib/bpf and the test. How can we avoid this type of
>> dependency or resolve it in a way it doesn't result in build
>> failures?
>
> Thanks, Shuah.
>
> The clang __builtin_preserve_access_index() intrinsic is
> introduced in LLVM9 (which just released last week) and
> the builtin and other CO-RE features are only supported
> in LLVM10 (current development branch) with more bug fixes
> and added features.
>
> I think we should do a feature test for llvm version and only
> enable these tests when llvm version >= 10.
Yes. If new tests depend on a particular llvm revision, the failing
the build is a regression. I would like to see older tests that don't
have dependency build and run.
thanks,
-- Shuah
^ permalink raw reply
* [PATCH net] net/rds: Check laddr_check before calling it
From: Ka-Cheong Poon @ 2019-09-24 15:51 UTC (permalink / raw)
To: netdev; +Cc: santosh.shilimkar, davem, rds-devel
In-Reply-To: <1568734158-18021-1-git-send-email-ka-cheong.poon@oracle.com>
In rds_bind(), laddr_check is called without checking if it is NULL or
not. And rs_transport should be reset if rds_add_bound() fails.
Fixes: c5c1a030a7db ("net/rds: An rds_sock is added too early to the hash table")
Reported-by: syzbot+fae39afd2101a17ec624@syzkaller.appspotmail.com
Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
---
net/rds/bind.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/rds/bind.c b/net/rds/bind.c
index 20c156a..5b5fb4c 100644
--- a/net/rds/bind.c
+++ b/net/rds/bind.c
@@ -244,7 +244,8 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
*/
if (rs->rs_transport) {
trans = rs->rs_transport;
- if (trans->laddr_check(sock_net(sock->sk),
+ if (!trans->laddr_check ||
+ trans->laddr_check(sock_net(sock->sk),
binding_addr, scope_id) != 0) {
ret = -ENOPROTOOPT;
goto out;
@@ -263,6 +264,8 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
sock_set_flag(sk, SOCK_RCU_FREE);
ret = rds_add_bound(rs, binding_addr, &port, scope_id);
+ if (ret)
+ rs->rs_transport = NULL;
out:
release_sock(sk);
--
1.8.3.1
^ permalink raw reply related
* [PATCH net v3 0/3] Fix Qdisc destroy issues caused by adding fine-grained locking to filter API
From: Vlad Buslov @ 2019-09-24 15:51 UTC (permalink / raw)
To: netdev; +Cc: jhs, xiyou.wangcong, jiri, davem, Vlad Buslov
TC filter API unlocking introduced several new fine-grained locks. The
change caused sleeping-while-atomic BUGs in several Qdiscs that call cls
APIs which need to obtain new mutex while holding sch tree spinlock. This
series fixes affected Qdiscs by ensuring that cls API that became sleeping
is only called outside of sch tree lock critical section.
Vlad Buslov (3):
net: sched: sch_htb: don't call qdisc_put() while holding tree lock
net: sched: multiq: don't call qdisc_put() while holding tree lock
net: sched: sch_sfb: don't call qdisc_put() while holding tree lock
net/sched/sch_htb.c | 4 +++-
net/sched/sch_multiq.c | 23 ++++++++++++++++-------
net/sched/sch_sfb.c | 7 ++++---
3 files changed, 23 insertions(+), 11 deletions(-)
--
2.21.0
^ permalink raw reply
* [PATCH net v3 1/3] net: sched: sch_htb: don't call qdisc_put() while holding tree lock
From: Vlad Buslov @ 2019-09-24 15:51 UTC (permalink / raw)
To: netdev; +Cc: jhs, xiyou.wangcong, jiri, davem, Vlad Buslov
In-Reply-To: <20190924155118.2488-1-vladbu@mellanox.com>
Recent changes that removed rtnl dependency from rules update path of tc
also made tcf_block_put() function sleeping. This function is called from
ops->destroy() of several Qdisc implementations, which in turn is called by
qdisc_put(). Some Qdiscs call qdisc_put() while holding sch tree spinlock,
which results sleeping-while-atomic BUG.
Steps to reproduce for htb:
tc qdisc add dev ens1f0 root handle 1: htb default 12
tc class add dev ens1f0 parent 1: classid 1:1 htb rate 100kbps ceil 100kbps
tc qdisc add dev ens1f0 parent 1:1 handle 40: sfq perturb 10
tc class add dev ens1f0 parent 1:1 classid 1:2 htb rate 100kbps ceil 100kbps
Resulting dmesg:
[ 4791.148551] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:909
[ 4791.151354] in_atomic(): 1, irqs_disabled(): 0, pid: 27273, name: tc
[ 4791.152805] INFO: lockdep is turned off.
[ 4791.153605] CPU: 19 PID: 27273 Comm: tc Tainted: G W 5.3.0-rc8+ #721
[ 4791.154336] Hardware name: Supermicro SYS-2028TP-DECR/X10DRT-P, BIOS 2.0b 03/30/2017
[ 4791.155075] Call Trace:
[ 4791.155803] dump_stack+0x85/0xc0
[ 4791.156529] ___might_sleep.cold+0xac/0xbc
[ 4791.157251] __mutex_lock+0x5b/0x960
[ 4791.157966] ? console_unlock+0x363/0x5d0
[ 4791.158676] ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 4791.159395] ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 4791.160103] tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 4791.160815] tcf_block_put_ext.part.0+0x21/0x50
[ 4791.161530] tcf_block_put+0x50/0x70
[ 4791.162233] sfq_destroy+0x15/0x50 [sch_sfq]
[ 4791.162936] qdisc_destroy+0x5f/0x160
[ 4791.163642] htb_change_class.cold+0x5df/0x69d [sch_htb]
[ 4791.164505] tc_ctl_tclass+0x19d/0x480
[ 4791.165360] rtnetlink_rcv_msg+0x170/0x4b0
[ 4791.166191] ? netlink_deliver_tap+0x95/0x400
[ 4791.166907] ? rtnl_dellink+0x2d0/0x2d0
[ 4791.167625] netlink_rcv_skb+0x49/0x110
[ 4791.168345] netlink_unicast+0x171/0x200
[ 4791.169058] netlink_sendmsg+0x224/0x3f0
[ 4791.169771] sock_sendmsg+0x5e/0x60
[ 4791.170475] ___sys_sendmsg+0x2ae/0x330
[ 4791.171183] ? ___sys_recvmsg+0x159/0x1f0
[ 4791.171894] ? do_wp_page+0x9c/0x790
[ 4791.172595] ? __handle_mm_fault+0xcd3/0x19e0
[ 4791.173309] __sys_sendmsg+0x59/0xa0
[ 4791.174024] do_syscall_64+0x5c/0xb0
[ 4791.174725] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 4791.175435] RIP: 0033:0x7f0aa41497b8
[ 4791.176129] Code: 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 65 8f 0c 00 8b 00 85 c0 75 17 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 28 89 5
4
[ 4791.177532] RSP: 002b:00007fff4e37d588 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
[ 4791.178243] RAX: ffffffffffffffda RBX: 000000005d8132f7 RCX: 00007f0aa41497b8
[ 4791.178947] RDX: 0000000000000000 RSI: 00007fff4e37d5f0 RDI: 0000000000000003
[ 4791.179662] RBP: 0000000000000000 R08: 0000000000000001 R09: 00000000020149a0
[ 4791.180382] R10: 0000000000404eda R11: 0000000000000246 R12: 0000000000000001
[ 4791.181100] R13: 000000000047f640 R14: 0000000000000000 R15: 0000000000000000
In htb_change_class() function save parent->leaf.q to local temporary
variable and put reference to it after sch tree lock is released in order
not to call potentially sleeping cls API in atomic section. This is safe to
do because Qdisc has already been reset by qdisc_purge_queue() inside sch
tree lock critical section.
Fixes: c266f64dbfa2 ("net: sched: protect block state with mutex")
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
---
Notes:
Changes V2 -> V3:
- Remove qdisc_put_empty() implementation introduced in V2. Use regular
qdisc_put() instead.
Changes V1 -> V2:
- Extend sch API with new qdisc_put_empty() function that has same
implementation as regular qdisc_put() but skips parts that reset qdisc
and free all packet buffers from gso_skb and skb_bad_txq queues.
- Use new qdisc_put_empty() instead of regular qdisc_put() in
htb_change_class().
net/sched/sch_htb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c
index 7bcf20ef9145..8184c87da8be 100644
--- a/net/sched/sch_htb.c
+++ b/net/sched/sch_htb.c
@@ -1302,6 +1302,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
struct htb_class *cl = (struct htb_class *)*arg, *parent;
struct nlattr *opt = tca[TCA_OPTIONS];
struct nlattr *tb[TCA_HTB_MAX + 1];
+ struct Qdisc *parent_qdisc = NULL;
struct tc_htb_opt *hopt;
u64 rate64, ceil64;
int warn = 0;
@@ -1401,7 +1402,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
if (parent && !parent->level) {
/* turn parent into inner node */
qdisc_purge_queue(parent->leaf.q);
- qdisc_put(parent->leaf.q);
+ parent_qdisc = parent->leaf.q;
if (parent->prio_activity)
htb_deactivate(q, parent);
@@ -1480,6 +1481,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
cl->cbuffer = PSCHED_TICKS2NS(hopt->cbuffer);
sch_tree_unlock(sch);
+ qdisc_put(parent_qdisc);
if (warn)
pr_warn("HTB: quantum of class %X is %s. Consider r2q change.\n",
--
2.21.0
^ permalink raw reply related
* [PATCH net v3 2/3] net: sched: multiq: don't call qdisc_put() while holding tree lock
From: Vlad Buslov @ 2019-09-24 15:51 UTC (permalink / raw)
To: netdev; +Cc: jhs, xiyou.wangcong, jiri, davem, Vlad Buslov
In-Reply-To: <20190924155118.2488-1-vladbu@mellanox.com>
Recent changes that removed rtnl dependency from rules update path of tc
also made tcf_block_put() function sleeping. This function is called from
ops->destroy() of several Qdisc implementations, which in turn is called by
qdisc_put(). Some Qdiscs call qdisc_put() while holding sch tree spinlock,
which results sleeping-while-atomic BUG.
Steps to reproduce for multiq:
tc qdisc add dev ens1f0 root handle 1: multiq
tc qdisc add dev ens1f0 parent 1:10 handle 50: sfq perturb 10
ethtool -L ens1f0 combined 2
tc qdisc change dev ens1f0 root handle 1: multiq
Resulting dmesg:
[ 5539.419344] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:909
[ 5539.420945] in_atomic(): 1, irqs_disabled(): 0, pid: 27658, name: tc
[ 5539.422435] INFO: lockdep is turned off.
[ 5539.423904] CPU: 21 PID: 27658 Comm: tc Tainted: G W 5.3.0-rc8+ #721
[ 5539.425400] Hardware name: Supermicro SYS-2028TP-DECR/X10DRT-P, BIOS 2.0b 03/30/2017
[ 5539.426911] Call Trace:
[ 5539.428380] dump_stack+0x85/0xc0
[ 5539.429823] ___might_sleep.cold+0xac/0xbc
[ 5539.431262] __mutex_lock+0x5b/0x960
[ 5539.432682] ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 5539.434103] ? __nla_validate_parse+0x51/0x840
[ 5539.435493] ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 5539.436903] tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 5539.438327] tcf_block_put_ext.part.0+0x21/0x50
[ 5539.439752] tcf_block_put+0x50/0x70
[ 5539.441165] sfq_destroy+0x15/0x50 [sch_sfq]
[ 5539.442570] qdisc_destroy+0x5f/0x160
[ 5539.444000] multiq_tune+0x14a/0x420 [sch_multiq]
[ 5539.445421] tc_modify_qdisc+0x324/0x840
[ 5539.446841] rtnetlink_rcv_msg+0x170/0x4b0
[ 5539.448269] ? netlink_deliver_tap+0x95/0x400
[ 5539.449691] ? rtnl_dellink+0x2d0/0x2d0
[ 5539.451116] netlink_rcv_skb+0x49/0x110
[ 5539.452522] netlink_unicast+0x171/0x200
[ 5539.453914] netlink_sendmsg+0x224/0x3f0
[ 5539.455304] sock_sendmsg+0x5e/0x60
[ 5539.456686] ___sys_sendmsg+0x2ae/0x330
[ 5539.458071] ? ___sys_recvmsg+0x159/0x1f0
[ 5539.459461] ? do_wp_page+0x9c/0x790
[ 5539.460846] ? __handle_mm_fault+0xcd3/0x19e0
[ 5539.462263] __sys_sendmsg+0x59/0xa0
[ 5539.463661] do_syscall_64+0x5c/0xb0
[ 5539.465044] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 5539.466454] RIP: 0033:0x7f1fe08177b8
[ 5539.467863] Code: 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 65 8f 0c 00 8b 00 85 c0 75 17 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 28 89 5
4
[ 5539.470906] RSP: 002b:00007ffe812de5d8 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
[ 5539.472483] RAX: ffffffffffffffda RBX: 000000005d8135e3 RCX: 00007f1fe08177b8
[ 5539.474069] RDX: 0000000000000000 RSI: 00007ffe812de640 RDI: 0000000000000003
[ 5539.475655] RBP: 0000000000000000 R08: 0000000000000001 R09: 000000000182e9b0
[ 5539.477203] R10: 0000000000404eda R11: 0000000000000246 R12: 0000000000000001
[ 5539.478699] R13: 000000000047f640 R14: 0000000000000000 R15: 0000000000000000
Rearrange locking in multiq_tune() in following ways:
- In loop that removes Qdiscs from disabled queues, call
qdisc_purge_queue() instead of qdisc_tree_flush_backlog() on Qdisc that
is being destroyed. Save the Qdisc in temporary allocated array and call
qdisc_put() on each element of the array after sch tree lock is released.
This is safe to do because Qdiscs have already been reset by
qdisc_purge_queue() inside sch tree lock critical section.
- Do the same change for second loop that initializes Qdiscs for newly
enabled queues in multiq_tune() function. Since sch tree lock is obtained
and released on each iteration of this loop, just call qdisc_put()
directly outside of critical section. Don't verify that old Qdisc is not
noop_qdisc before releasing reference to it because such check is already
performed by qdisc_put*() functions.
Fixes: c266f64dbfa2 ("net: sched: protect block state with mutex")
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
---
Notes:
Changes V2 -> V3:
- Use regular qdisc_put() instead of qdisc_put_empty() introduced in V2.
Changes V1 -> V2:
- Refactor first loop in multiq_tune() to save child Qdiscs that are being
removed into an array and call qdisc_put_empty() on all of its elements
after sch tree lock critical section. Revert the change in V1 that
obtained and released sch tree lock on every loop iteration.
- Use qdisc_purge_queue() instead of qdisc_tree_flush_backlog() to properly
reset Qdiscs inside sch tree lock critical section.
- Use qdisc_put_empty() in both loops of multiq_tune() instead of regular
qdisc_put().
net/sched/sch_multiq.c | 23 ++++++++++++++++-------
1 file changed, 16 insertions(+), 7 deletions(-)
diff --git a/net/sched/sch_multiq.c b/net/sched/sch_multiq.c
index e1087746f6a2..b2b7fdb06fc6 100644
--- a/net/sched/sch_multiq.c
+++ b/net/sched/sch_multiq.c
@@ -174,7 +174,8 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt,
{
struct multiq_sched_data *q = qdisc_priv(sch);
struct tc_multiq_qopt *qopt;
- int i;
+ struct Qdisc **removed;
+ int i, n_removed = 0;
if (!netif_is_multiqueue(qdisc_dev(sch)))
return -EOPNOTSUPP;
@@ -185,6 +186,11 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt,
qopt->bands = qdisc_dev(sch)->real_num_tx_queues;
+ removed = kmalloc(sizeof(*removed) * (q->max_bands - q->bands),
+ GFP_KERNEL);
+ if (!removed)
+ return -ENOMEM;
+
sch_tree_lock(sch);
q->bands = qopt->bands;
for (i = q->bands; i < q->max_bands; i++) {
@@ -192,13 +198,17 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt,
struct Qdisc *child = q->queues[i];
q->queues[i] = &noop_qdisc;
- qdisc_tree_flush_backlog(child);
- qdisc_put(child);
+ qdisc_purge_queue(child);
+ removed[n_removed++] = child;
}
}
sch_tree_unlock(sch);
+ for (i = 0; i < n_removed; i++)
+ qdisc_put(removed[i]);
+ kfree(removed);
+
for (i = 0; i < q->bands; i++) {
if (q->queues[i] == &noop_qdisc) {
struct Qdisc *child, *old;
@@ -213,11 +223,10 @@ static int multiq_tune(struct Qdisc *sch, struct nlattr *opt,
if (child != &noop_qdisc)
qdisc_hash_add(child, true);
- if (old != &noop_qdisc) {
- qdisc_tree_flush_backlog(old);
- qdisc_put(old);
- }
+ if (old != &noop_qdisc)
+ qdisc_purge_queue(old);
sch_tree_unlock(sch);
+ qdisc_put(old);
}
}
}
--
2.21.0
^ permalink raw reply related
* [PATCH net v3 3/3] net: sched: sch_sfb: don't call qdisc_put() while holding tree lock
From: Vlad Buslov @ 2019-09-24 15:51 UTC (permalink / raw)
To: netdev
Cc: jhs, xiyou.wangcong, jiri, davem, Vlad Buslov,
syzbot+ac54455281db908c581e
In-Reply-To: <20190924155118.2488-1-vladbu@mellanox.com>
Recent changes that removed rtnl dependency from rules update path of tc
also made tcf_block_put() function sleeping. This function is called from
ops->destroy() of several Qdisc implementations, which in turn is called by
qdisc_put(). Some Qdiscs call qdisc_put() while holding sch tree spinlock,
which results sleeping-while-atomic BUG.
Steps to reproduce for sfb:
tc qdisc add dev ens1f0 handle 1: root sfb
tc qdisc add dev ens1f0 parent 1:10 handle 50: sfq perturb 10
tc qdisc change dev ens1f0 root handle 1: sfb
Resulting dmesg:
[ 7265.938717] BUG: sleeping function called from invalid context at kernel/locking/mutex.c:909
[ 7265.940152] in_atomic(): 1, irqs_disabled(): 0, pid: 28579, name: tc
[ 7265.941455] INFO: lockdep is turned off.
[ 7265.942744] CPU: 11 PID: 28579 Comm: tc Tainted: G W 5.3.0-rc8+ #721
[ 7265.944065] Hardware name: Supermicro SYS-2028TP-DECR/X10DRT-P, BIOS 2.0b 03/30/2017
[ 7265.945396] Call Trace:
[ 7265.946709] dump_stack+0x85/0xc0
[ 7265.947994] ___might_sleep.cold+0xac/0xbc
[ 7265.949282] __mutex_lock+0x5b/0x960
[ 7265.950543] ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 7265.951803] ? tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 7265.953022] tcf_chain0_head_change_cb_del.isra.0+0x1b/0xf0
[ 7265.954248] tcf_block_put_ext.part.0+0x21/0x50
[ 7265.955478] tcf_block_put+0x50/0x70
[ 7265.956694] sfq_destroy+0x15/0x50 [sch_sfq]
[ 7265.957898] qdisc_destroy+0x5f/0x160
[ 7265.959099] sfb_change+0x175/0x330 [sch_sfb]
[ 7265.960304] tc_modify_qdisc+0x324/0x840
[ 7265.961503] rtnetlink_rcv_msg+0x170/0x4b0
[ 7265.962692] ? netlink_deliver_tap+0x95/0x400
[ 7265.963876] ? rtnl_dellink+0x2d0/0x2d0
[ 7265.965064] netlink_rcv_skb+0x49/0x110
[ 7265.966251] netlink_unicast+0x171/0x200
[ 7265.967427] netlink_sendmsg+0x224/0x3f0
[ 7265.968595] sock_sendmsg+0x5e/0x60
[ 7265.969753] ___sys_sendmsg+0x2ae/0x330
[ 7265.970916] ? ___sys_recvmsg+0x159/0x1f0
[ 7265.972074] ? do_wp_page+0x9c/0x790
[ 7265.973233] ? __handle_mm_fault+0xcd3/0x19e0
[ 7265.974407] __sys_sendmsg+0x59/0xa0
[ 7265.975591] do_syscall_64+0x5c/0xb0
[ 7265.976753] entry_SYSCALL_64_after_hwframe+0x49/0xbe
[ 7265.977938] RIP: 0033:0x7f229069f7b8
[ 7265.979117] Code: 89 02 48 c7 c0 ff ff ff ff eb bb 0f 1f 80 00 00 00 00 f3 0f 1e fa 48 8d 05 65 8f 0c 00 8b 00 85 c0 75 17 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 58 c3 0f 1f 80 00 00 00 00 48 83 ec 28 89 5
4
[ 7265.981681] RSP: 002b:00007ffd7ed2d158 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
[ 7265.983001] RAX: ffffffffffffffda RBX: 000000005d813ca1 RCX: 00007f229069f7b8
[ 7265.984336] RDX: 0000000000000000 RSI: 00007ffd7ed2d1c0 RDI: 0000000000000003
[ 7265.985682] RBP: 0000000000000000 R08: 0000000000000001 R09: 000000000165c9a0
[ 7265.987021] R10: 0000000000404eda R11: 0000000000000246 R12: 0000000000000001
[ 7265.988309] R13: 000000000047f640 R14: 0000000000000000 R15: 0000000000000000
In sfb_change() function use qdisc_purge_queue() instead of
qdisc_tree_flush_backlog() to properly reset old child Qdisc and save
pointer to it into local temporary variable. Put reference to Qdisc after
sch tree lock is released in order not to call potentially sleeping cls API
in atomic section. This is safe to do because Qdisc has already been reset
by qdisc_purge_queue() inside sch tree lock critical section.
Reported-by: syzbot+ac54455281db908c581e@syzkaller.appspotmail.com
Fixes: c266f64dbfa2 ("net: sched: protect block state with mutex")
Suggested-by: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Vlad Buslov <vladbu@mellanox.com>
---
Notes:
Changes V2 -> V3:
- Use regular qdisc_put() instead of qdisc_put_empty() introduced in V2.
Changes V1 -> V2:
- Use qdisc_purge_queue() instead of qdisc_tree_flush_backlog() to properly
reset Qdiscs inside sch tree lock critical section.
- Call qdisc_put_empty() instead of regular qdisc_put() after sch tree lock
is released.
net/sched/sch_sfb.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
index 1dff8506a715..d448fe3068e5 100644
--- a/net/sched/sch_sfb.c
+++ b/net/sched/sch_sfb.c
@@ -488,7 +488,7 @@ static int sfb_change(struct Qdisc *sch, struct nlattr *opt,
struct netlink_ext_ack *extack)
{
struct sfb_sched_data *q = qdisc_priv(sch);
- struct Qdisc *child;
+ struct Qdisc *child, *old;
struct nlattr *tb[TCA_SFB_MAX + 1];
const struct tc_sfb_qopt *ctl = &sfb_default_ops;
u32 limit;
@@ -518,8 +518,8 @@ static int sfb_change(struct Qdisc *sch, struct nlattr *opt,
qdisc_hash_add(child, true);
sch_tree_lock(sch);
- qdisc_tree_flush_backlog(q->qdisc);
- qdisc_put(q->qdisc);
+ qdisc_purge_queue(q->qdisc);
+ old = q->qdisc;
q->qdisc = child;
q->rehash_interval = msecs_to_jiffies(ctl->rehash_interval);
@@ -542,6 +542,7 @@ static int sfb_change(struct Qdisc *sch, struct nlattr *opt,
sfb_init_perturbation(1, q);
sch_tree_unlock(sch);
+ qdisc_put(old);
return 0;
}
--
2.21.0
^ permalink raw reply related
* Re: Linux 5.4 - bpf test build fails
From: Cristian Marussi @ 2019-09-24 15:52 UTC (permalink / raw)
To: Shuah Khan, Alexei Starovoitov, Daniel Borkmann
Cc: open list:KERNEL SELFTEST FRAMEWORK, bpf, Networking,
David S. Miller
In-Reply-To: <742ecabe-45ce-cf6e-2540-25d6dc23c45f@linuxfoundation.org>
Hi Shuah
On 24/09/2019 16:26, Shuah Khan wrote:
> Hi Alexei and Daniel,
>
> bpf test doesn't build on Linux 5.4 mainline. Do you know what's
> happening here.
>
>
> make -C tools/testing/selftests/bpf/
side question, since I'm writing arm64/ tests.
my "build-testcases" following the KSFT docs are:
make kselftest
make TARGETS=arm64 kselftest
make -C tools/testing/selftests/
make -C tools/testing/selftests/ INSTALL_PATH=<install-path> install
make TARGETS=arm64 -C tools/testing/selftests/
make TARGETS=arm64 -C tools/testing/selftests/ INSTALL_PATH=<install-path> install
./kselftest_install.sh <install-path>
(and related clean targets...)
but definitely NOT
make -C tools/testing/selftests/arm64
(for simplicity....due to the subdirs structure under tools/testing/selftests/arm64/)
am I wrong ?
Thanks
Cristian
>
> -c progs/test_core_reloc_ptr_as_arr.c -o - || echo "clang failed") | \
> llc -march=bpf -mcpu=generic -filetype=obj -o
> /mnt/data/lkml/linux_5.4/tools/testing/selftests/bpf/test_core_reloc_ptr_as_arr.o
> progs/test_core_reloc_ptr_as_arr.c:25:6: error: use of unknown builtin
> '__builtin_preserve_access_index' [-Wimplicit-function-declaration]
> if (BPF_CORE_READ(&out->a, &in[2].a))
> ^
> ./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
> __builtin_preserve_access_index(src))
> ^
> progs/test_core_reloc_ptr_as_arr.c:25:6: warning: incompatible integer to
> pointer conversion passing 'int' to parameter of type 'const void *'
> [-Wint-conversion]
> if (BPF_CORE_READ(&out->a, &in[2].a))
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ./bpf_helpers.h:533:10: note: expanded from macro 'BPF_CORE_READ'
> __builtin_preserve_access_index(src))
> ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> 1 warning and 1 error generated.
> llc: error: llc: <stdin>:1:1: error: expected top-level entity
> clang failed
>
> Also
>
> make TARGETS=bpf kselftest fails as well. Dependency between
> tools/lib/bpf and the test. How can we avoid this type of
> dependency or resolve it in a way it doesn't result in build
> failures?
>
> thanks,
> -- Shuah
>
^ permalink raw reply
* Re: [PATCH net] net/rds: Check laddr_check before calling it
From: Ka-Cheong Poon @ 2019-09-24 15:58 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: netdev, santosh.shilimkar, davem, rds-devel
In-Reply-To: <20190920180959.7920f2c3@cakuba.netronome.com>
On 9/21/19 9:09 AM, Jakub Kicinski wrote:
> On Tue, 17 Sep 2019 08:29:18 -0700, Ka-Cheong Poon wrote:
>> In rds_bind(), laddr_check is called without checking if it is NULL or
>> not. And rs_transport should be reset if rds_add_bound() fails.
>>
>> Reported-by: syzbot+fae39afd2101a17ec624@syzkaller.appspotmail.com
>> Signed-off-by: Ka-Cheong Poon <ka-cheong.poon@oracle.com>
>
> Looks good, but could you please provide a fixes tag?
Done. Thanks.
--
K. Poon
ka-cheong.poon@oracle.com
^ permalink raw reply
* [PATCH v2] dimlib: make DIMLIB a hidden symbol
From: Uwe Kleine-König @ 2019-09-24 16:02 UTC (permalink / raw)
To: Tal Gilboa, Saeed Mahameed, David Miller; +Cc: netdev
In-Reply-To: <20190924.164528.724219923520816886.davem@davemloft.net>
According to Tal Gilboa the only benefit from DIM comes from a driver
that uses it. So it doesn't make sense to make this symbol user visible,
instead all drivers that use it should select it (as is already the case
AFAICT).
Signed-off-by: Uwe Kleine-König <uwe@kleine-koenig.org>
---
Hello David,
On Tue, Sep 24, 2019 at 04:45:28PM +0200, David Miller wrote:
> Since this doesn't apply due to the moderation typo being elsewhere, I'd
> really like you to fix up this submission to properly be against 'net'.
I thought it would be possible to git-apply my patch with the -3 option.
I even tested that, but obviously it only applies to my tree that has
the git object with the typo fixed. Sorry for the extra effort I'm
forcing on you. This patch applies to your public tree from just now.
Best regads
Uwe
lib/Kconfig | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/lib/Kconfig b/lib/Kconfig
index 4e6b1c3e4c98..d7fc9eb33b9b 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -555,8 +555,7 @@ config SIGNATURE
Implementation is done using GnuPG MPI library
config DIMLIB
- bool "DIM library"
- default y
+ bool
help
Dynamic Interrupt Moderation library.
Implements an algorithm for dynamically change CQ modertion values
--
2.23.0
^ permalink raw reply related
* Re: Linux 5.4 - bpf test build fails
From: Shuah Khan @ 2019-09-24 16:03 UTC (permalink / raw)
To: Cristian Marussi, Alexei Starovoitov, Daniel Borkmann
Cc: open list:KERNEL SELFTEST FRAMEWORK, bpf, Networking,
David S. Miller, skh >> Shuah Khan
In-Reply-To: <1d1bbc01-5cf4-72e6-76b3-754d23366c8f@arm.com>
On 9/24/19 9:52 AM, Cristian Marussi wrote:
> Hi Shuah
>
> On 24/09/2019 16:26, Shuah Khan wrote:
>> Hi Alexei and Daniel,
>>
>> bpf test doesn't build on Linux 5.4 mainline. Do you know what's
>> happening here.
>>
>>
>> make -C tools/testing/selftests/bpf/
>
> side question, since I'm writing arm64/ tests.
>
> my "build-testcases" following the KSFT docs are:
>
> make kselftest
> make TARGETS=arm64 kselftest
> make -C tools/testing/selftests/
> make -C tools/testing/selftests/ INSTALL_PATH=<install-path> install
> make TARGETS=arm64 -C tools/testing/selftests/
> make TARGETS=arm64 -C tools/testing/selftests/ INSTALL_PATH=<install-path> install
> ./kselftest_install.sh <install-path>
>
> (and related clean targets...)
>
> but definitely NOT
>
> make -C tools/testing/selftests/arm64
>
> (for simplicity....due to the subdirs structure under tools/testing/selftests/arm64/)
>
Some people like to build their tests using:
make -C tools/testing/selftests/<testdir>
I have been continuing to support it for that reason.
Tests with subdirs can handle this case. Pleas see android and futex
tests.
thanks,
-- Shuah
^ permalink raw reply
* Re: [PATCH 2/3] clk: let init callback return an error code
From: Andrew Lunn @ 2019-09-24 16:19 UTC (permalink / raw)
To: Jerome Brunet
Cc: Michael Turquette, Stephen Boyd, linux-clk, linux-kernel,
Heiko Stuebner, Tero Kristo, Florian Fainelli, Heiner Kallweit,
David S. Miller, netdev, linux-amlogic, linux-arm-msm,
linux-rockchip, linux-omap
In-Reply-To: <20190924123954.31561-3-jbrunet@baylibre.com>
On Tue, Sep 24, 2019 at 02:39:53PM +0200, Jerome Brunet wrote:
> If the init callback is allowed to request resources, it needs a return
> value to report the outcome of such a request.
>
> Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
> ---
>
> Sorry about the spam.
> This patch change quite a few files so I have tried to Cc the
> relevant people. Stephen, You may notice that I have added a
> couple of the network people. You need an Ack from one of them
> since the Amlogic G12a mdio mux has a clock which uses the .init()
> callback
> static void __init of_ti_clockdomain_setup(struct device_node *node)
> diff --git a/drivers/net/phy/mdio-mux-meson-g12a.c b/drivers/net/phy/mdio-mux-meson-g12a.c
> index 7a9ad54582e1..bf86c9c7a288 100644
> --- a/drivers/net/phy/mdio-mux-meson-g12a.c
> +++ b/drivers/net/phy/mdio-mux-meson-g12a.c
> @@ -123,7 +123,7 @@ static int g12a_ephy_pll_is_enabled(struct clk_hw *hw)
> return (val & PLL_CTL0_LOCK_DIG) ? 1 : 0;
> }
>
> -static void g12a_ephy_pll_init(struct clk_hw *hw)
> +static int g12a_ephy_pll_init(struct clk_hw *hw)
> {
> struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
>
> @@ -136,6 +136,8 @@ static void g12a_ephy_pll_init(struct clk_hw *hw)
> writel(0x20200000, pll->base + ETH_PLL_CTL5);
> writel(0x0000c002, pll->base + ETH_PLL_CTL6);
> writel(0x00000023, pll->base + ETH_PLL_CTL7);
> +
> + return 0;
> }
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
It should be safe to merge this via the clk tree. You would probably
know about an possible merge conflicts, since you wrote this driver!
Andrew
^ permalink raw reply
* [PATCH net] bpf/xskmap: Return ERR_PTR for failure case instead of NULL.
From: Jonathan Lemon @ 2019-09-24 16:24 UTC (permalink / raw)
To: daniel, bjorn.topel, netdev; +Cc: kernel-team
When kzalloc() failed, NULL was returned to the caller, which
tested the pointer with IS_ERR(), which didn't match, so the
pointer was used later, resulting in a NULL dereference.
Return ERR_PTR(-ENOMEM) instead of NULL.
Reported-by: syzbot+491c1b7565ba9069ecae@syzkaller.appspotmail.com
Fixes: 0402acd683c6 ("xsk: remove AF_XDP socket from map when the socket is released")
Signed-off-by: Jonathan Lemon <jonathan.lemon@gmail.com>
---
kernel/bpf/xskmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/xskmap.c b/kernel/bpf/xskmap.c
index 942c662e2eed..82a1ffe15dfa 100644
--- a/kernel/bpf/xskmap.c
+++ b/kernel/bpf/xskmap.c
@@ -37,7 +37,7 @@ static struct xsk_map_node *xsk_map_node_alloc(struct xsk_map *map,
node = kzalloc(sizeof(*node), GFP_ATOMIC | __GFP_NOWARN);
if (!node)
- return NULL;
+ return ERR_PTR(-ENOMEM);
err = xsk_map_inc(map);
if (err) {
--
2.17.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox