* [PATCH AUTOSEL 4.9 01/22] netfilter: nfnetlink: avoid deadlock due to synchronous request_module
From: Sasha Levin @ 2019-08-02 13:25 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Florian Westphal, Thomas Jarosch, Juliana Rodrigueiro,
Pablo Neira Ayuso, Sasha Levin, netfilter-devel, coreteam, netdev
From: Florian Westphal <fw@strlen.de>
[ Upstream commit 1b0890cd60829bd51455dc5ad689ed58c4408227 ]
Thomas and Juliana report a deadlock when running:
(rmmod nf_conntrack_netlink/xfrm_user)
conntrack -e NEW -E &
modprobe -v xfrm_user
They provided following analysis:
conntrack -e NEW -E
netlink_bind()
netlink_lock_table() -> increases "nl_table_users"
nfnetlink_bind()
# does not unlock the table as it's locked by netlink_bind()
__request_module()
call_usermodehelper_exec()
This triggers "modprobe nf_conntrack_netlink" from kernel, netlink_bind()
won't return until modprobe process is done.
"modprobe xfrm_user":
xfrm_user_init()
register_pernet_subsys()
-> grab pernet_ops_rwsem
..
netlink_table_grab()
calls schedule() as "nl_table_users" is non-zero
so modprobe is blocked because netlink_bind() increased
nl_table_users while also holding pernet_ops_rwsem.
"modprobe nf_conntrack_netlink" runs and inits nf_conntrack_netlink:
ctnetlink_init()
register_pernet_subsys()
-> blocks on "pernet_ops_rwsem" thanks to xfrm_user module
both modprobe processes wait on one another -- neither can make
progress.
Switch netlink_bind() to "nowait" modprobe -- this releases the netlink
table lock, which then allows both modprobe instances to complete.
Reported-by: Thomas Jarosch <thomas.jarosch@intra2net.com>
Reported-by: Juliana Rodrigueiro <juliana.rodrigueiro@intra2net.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nfnetlink.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 2278d9ab723bf..9837a61cb3e3b 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -490,7 +490,7 @@ static int nfnetlink_bind(struct net *net, int group)
ss = nfnetlink_get_subsys(type << 8);
rcu_read_unlock();
if (!ss)
- request_module("nfnetlink-subsys-%d", type);
+ request_module_nowait("nfnetlink-subsys-%d", type);
return 0;
}
#endif
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 4.14 03/30] netfilter: Fix rpfilter dropping vrf packets by mistake
From: Sasha Levin @ 2019-08-02 13:23 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Miaohe Lin, Pablo Neira Ayuso, Sasha Levin, netfilter-devel,
coreteam, netdev
In-Reply-To: <20190802132422.13963-1-sashal@kernel.org>
From: Miaohe Lin <linmiaohe@huawei.com>
[ Upstream commit b575b24b8eee37f10484e951b62ce2a31c579775 ]
When firewalld is enabled with ipv4/ipv6 rpfilter, vrf
ipv4/ipv6 packets will be dropped. Vrf device will pass
through netfilter hook twice. One with enslaved device
and another one with l3 master device. So in device may
dismatch witch out device because out device is always
enslaved device.So failed with the check of the rpfilter
and drop the packets by mistake.
Signed-off-by: Miaohe Lin <linmiaohe@huawei.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/netfilter/ipt_rpfilter.c | 1 +
net/ipv6/netfilter/ip6t_rpfilter.c | 8 ++++++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
index 37fb9552e8589..341d1bd637af2 100644
--- a/net/ipv4/netfilter/ipt_rpfilter.c
+++ b/net/ipv4/netfilter/ipt_rpfilter.c
@@ -96,6 +96,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0;
flow.flowi4_tos = RT_TOS(iph->tos);
flow.flowi4_scope = RT_SCOPE_UNIVERSE;
+ flow.flowi4_oif = l3mdev_master_ifindex_rcu(xt_in(par));
return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert;
}
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c
index 40eb16bd97860..d535768bea0fd 100644
--- a/net/ipv6/netfilter/ip6t_rpfilter.c
+++ b/net/ipv6/netfilter/ip6t_rpfilter.c
@@ -58,7 +58,9 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
if (rpfilter_addr_linklocal(&iph->saddr)) {
lookup_flags |= RT6_LOOKUP_F_IFACE;
fl6.flowi6_oif = dev->ifindex;
- } else if ((flags & XT_RPFILTER_LOOSE) == 0)
+ /* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */
+ } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev) ||
+ (flags & XT_RPFILTER_LOOSE) == 0)
fl6.flowi6_oif = dev->ifindex;
rt = (void *) ip6_route_lookup(net, &fl6, lookup_flags);
@@ -73,7 +75,9 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
goto out;
}
- if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE))
+ if (rt->rt6i_idev->dev == dev ||
+ l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == dev->ifindex ||
+ (flags & XT_RPFILTER_LOOSE))
ret = true;
out:
ip6_rt_put(rt);
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.2 30/76] allocate_flower_entry: should check for null deref
From: Sasha Levin @ 2019-08-02 13:19 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Navid Emamdoost, David S . Miller, Sasha Levin, netdev
In-Reply-To: <20190802131951.11600-1-sashal@kernel.org>
From: Navid Emamdoost <navid.emamdoost@gmail.com>
[ Upstream commit bb1320834b8a80c6ac2697ab418d066981ea08ba ]
allocate_flower_entry does not check for allocation success, but tries
to deref the result. I only moved the spin_lock under null check, because
the caller is checking allocation's status at line 652.
Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
index cfaf8f618d1f3..56742fa0c1af6 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_tc_flower.c
@@ -67,7 +67,8 @@ static struct ch_tc_pedit_fields pedits[] = {
static struct ch_tc_flower_entry *allocate_flower_entry(void)
{
struct ch_tc_flower_entry *new = kzalloc(sizeof(*new), GFP_KERNEL);
- spin_lock_init(&new->lock);
+ if (new)
+ spin_lock_init(&new->lock);
return new;
}
--
2.20.1
^ permalink raw reply related
* [PATCH AUTOSEL 5.2 06/76] netfilter: nf_tables: fix module autoload for redir
From: Sasha Levin @ 2019-08-02 13:18 UTC (permalink / raw)
To: linux-kernel, stable
Cc: Christian Hesse, Pablo Neira Ayuso, Sasha Levin, netfilter-devel,
coreteam, netdev
In-Reply-To: <20190802131951.11600-1-sashal@kernel.org>
From: Christian Hesse <mail@eworm.de>
[ Upstream commit f41828ee10b36644bb2b2bfa9dd1d02f55aa0516 ]
Fix expression for autoloading.
Fixes: 5142967ab524 ("netfilter: nf_tables: fix module autoload with inet family")
Signed-off-by: Christian Hesse <mail@eworm.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nft_redir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nft_redir.c b/net/netfilter/nft_redir.c
index 8487eeff5c0ec..43eeb1f609f13 100644
--- a/net/netfilter/nft_redir.c
+++ b/net/netfilter/nft_redir.c
@@ -291,4 +291,4 @@ module_exit(nft_redir_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
-MODULE_ALIAS_NFT_EXPR("nat");
+MODULE_ALIAS_NFT_EXPR("redir");
--
2.20.1
^ permalink raw reply related
* Re: [PATCH net-next v5 5/6] flow_offload: support get flow_block immediately
From: wenxu @ 2019-08-02 13:09 UTC (permalink / raw)
To: Jakub Kicinski; +Cc: jiri, pablo, fw, netfilter-devel, netdev, John Hurley
In-Reply-To: <bac5c6a5-8a1b-ee74-988b-6c2a71885761@ucloud.cn>
在 2019/8/2 18:45, wenxu 写道:
> On 8/2/2019 7:11 AM, Jakub Kicinski wrote:
>> On Thu, 1 Aug 2019 11:03:46 +0800, wenxu@ucloud.cn wrote:
>>> From: wenxu <wenxu@ucloud.cn>
>>>
>>> The new flow-indr-block can't get the tcf_block
>>> directly. It provide a callback list to find the flow_block immediately
>>> when the device register and contain a ingress block.
>>>
>>> Signed-off-by: wenxu <wenxu@ucloud.cn>
>> First of all thanks for splitting the series up into more patches,
>> it is easier to follow the logic now!
>>
>>> @@ -328,6 +348,7 @@ struct flow_indr_block_dev {
>>>
>>> INIT_LIST_HEAD(&indr_dev->cb_list);
>>> indr_dev->dev = dev;
>>> + flow_get_default_block(indr_dev);
>>> if (rhashtable_insert_fast(&indr_setup_block_ht, &indr_dev->ht_node,
>>> flow_indr_setup_block_ht_params)) {
>>> kfree(indr_dev);
>> I wonder if it's still practical to keep the block information in the
>> indr_dev structure at all. The way this used to work was:
>>
>>
>> [hash table of devices] --------------
>> | | netdev |
>> | | refcnt |
>> indir_dev[tun0]| ------ | cached block | ---- [ TC block ]
>> | | callbacks | .
>> | -------------- \__ [cb, cb_priv, cb_ident]
>> | [cb, cb_priv, cb_ident]
>> | --------------
>> | | netdev |
>> | | refcnt |
>> indir_dev[tun1]| ------ | cached block | ---- [ TC block ]
>> | | callbacks |.
>> ----------------- -------------- \__ [cb, cb_priv, cb_ident]
>> [cb, cb_priv, cb_ident]
>>
>>
>> In the example above we have two tunnels tun0 and tun1, each one has a
>> indr_dev structure allocated, and for each one of them two drivers
>> registered for callbacks (hence the callbacks list has two entries).
>>
>> We used to cache the TC block in the indr_dev structure, but now that
>> there are multiple subsytems using the indr_dev we either have to have
>> a list of cached blocks (with entries for each subsystem) or just always
>> iterate over the subsystems :(
>>
>> After all the same device may have both a TC block and a NFT block.
>>
>> I think always iterating would be easier:
>>
>> The indr_dev struct would no longer have the block pointer, instead
>> when new driver registers for the callback instead of:
>>
>> if (indr_dev->ing_cmd_cb)
>> indr_dev->ing_cmd_cb(indr_dev->dev, indr_dev->flow_block,
>> indr_block_cb->cb, indr_block_cb->cb_priv,
>> FLOW_BLOCK_BIND);
>>
>> We'd have something like the loop in flow_get_default_block():
>>
>> for each (subsystem)
>> subsystem->handle_new_indir_cb(indr_dev, cb);
>>
>> And then per-subsystem logic would actually call the cb. Or:
>>
>> for each (subsystem)
>> block = get_default_block(indir_dev)
>> indr_dev->ing_cmd_cb(...)
> nft dev chian is also based on register_netdevice_notifier, So for unregister case,
>
> the basechian(block) of nft maybe delete before the __tc_indr_block_cb_unregister. is right?
>
> So maybe we can cache the block as a list of all the subsystem in indr_dev ?
when the device is unregister the nft netdev chain related to this device will also be delete through netdevice_notifier
. So for unregister case,the basechian(block) of nft maybe delete before the __tc_indr_block_cb_unregister.
cache for the block is not work because the chain already be delete and free. Maybe it improve the prio of
rep_netdev_event can help this?
>
>
^ permalink raw reply
* [PATCH] niu: Use refcount_t for refcount
From: Chuhong Yuan @ 2019-08-02 12:57 UTC (permalink / raw)
Cc: David S . Miller, netdev, linux-kernel, Chuhong Yuan
refcount_t is better for reference counters since its
implementation can prevent overflows.
So convert atomic_t ref counters to refcount_t.
Also convert refcount from 0-based to 1-based.
Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
---
drivers/net/ethernet/sun/niu.c | 6 +++---
drivers/net/ethernet/sun/niu.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c
index 0bc5863bffeb..5bf096e51db7 100644
--- a/drivers/net/ethernet/sun/niu.c
+++ b/drivers/net/ethernet/sun/niu.c
@@ -9464,7 +9464,7 @@ static struct niu_parent *niu_new_parent(struct niu *np,
memcpy(&p->id, id, sizeof(*id));
p->plat_type = ptype;
INIT_LIST_HEAD(&p->list);
- atomic_set(&p->refcnt, 0);
+ refcount_set(&p->refcnt, 1);
list_add(&p->list, &niu_parent_list);
spin_lock_init(&p->lock);
@@ -9524,7 +9524,7 @@ static struct niu_parent *niu_get_parent(struct niu *np,
port_name);
if (!err) {
p->ports[port] = np;
- atomic_inc(&p->refcnt);
+ refcount_inc(&p->refcnt);
}
}
mutex_unlock(&niu_parent_lock);
@@ -9552,7 +9552,7 @@ static void niu_put_parent(struct niu *np)
p->ports[port] = NULL;
np->parent = NULL;
- if (atomic_dec_and_test(&p->refcnt)) {
+ if (refcount_dec_and_test(&p->refcnt)) {
list_del(&p->list);
platform_device_unregister(p->plat_dev);
}
diff --git a/drivers/net/ethernet/sun/niu.h b/drivers/net/ethernet/sun/niu.h
index 04c215f91fc0..755e6dd4c903 100644
--- a/drivers/net/ethernet/sun/niu.h
+++ b/drivers/net/ethernet/sun/niu.h
@@ -3071,7 +3071,7 @@ struct niu_parent {
struct niu *ports[NIU_MAX_PORTS];
- atomic_t refcnt;
+ refcount_t refcnt;
struct list_head list;
spinlock_t lock;
--
2.20.1
^ permalink raw reply related
* [PATCH] mkiss: Use refcount_t for refcount
From: Chuhong Yuan @ 2019-08-02 12:57 UTC (permalink / raw)
Cc: David S . Miller, netdev, linux-kernel, Chuhong Yuan
refcount_t is better for reference counters since its
implementation can prevent overflows.
So convert atomic_t ref counters to refcount_t.
Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
---
drivers/net/hamradio/mkiss.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 442018ccd65e..b0afd7d13553 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -70,7 +70,7 @@ struct mkiss {
#define CRC_MODE_FLEX_TEST 3
#define CRC_MODE_SMACK_TEST 4
- atomic_t refcnt;
+ refcount_t refcnt;
struct completion dead;
};
@@ -668,7 +668,7 @@ static struct mkiss *mkiss_get(struct tty_struct *tty)
read_lock(&disc_data_lock);
ax = tty->disc_data;
if (ax)
- atomic_inc(&ax->refcnt);
+ refcount_inc(&ax->refcnt);
read_unlock(&disc_data_lock);
return ax;
@@ -676,7 +676,7 @@ static struct mkiss *mkiss_get(struct tty_struct *tty)
static void mkiss_put(struct mkiss *ax)
{
- if (atomic_dec_and_test(&ax->refcnt))
+ if (refcount_dec_and_test(&ax->refcnt))
complete(&ax->dead);
}
@@ -704,7 +704,7 @@ static int mkiss_open(struct tty_struct *tty)
ax->dev = dev;
spin_lock_init(&ax->buflock);
- atomic_set(&ax->refcnt, 1);
+ refcount_set(&ax->refcnt, 1);
init_completion(&ax->dead);
ax->tty = tty;
@@ -784,7 +784,7 @@ static void mkiss_close(struct tty_struct *tty)
* We have now ensured that nobody can start using ap from now on, but
* we have to wait for all existing users to finish.
*/
- if (!atomic_dec_and_test(&ax->refcnt))
+ if (!refcount_dec_and_test(&ax->refcnt))
wait_for_completion(&ax->dead);
/*
* Halt the transmit queue so that a new transmit cannot scribble
--
2.20.1
^ permalink raw reply related
* Re: [PATCH V2 7/9] vhost: do not use RCU to synchronize MMU notifier with worker
From: Jason Gunthorpe @ 2019-08-02 12:46 UTC (permalink / raw)
To: Jason Wang; +Cc: mst, kvm, virtualization, netdev, linux-kernel, linux-mm
In-Reply-To: <42ead87b-1749-4c73-cbe4-29dbeb945041@redhat.com>
On Fri, Aug 02, 2019 at 05:40:07PM +0800, Jason Wang wrote:
> > This must be a proper barrier, like a spinlock, mutex, or
> > synchronize_rcu.
>
>
> I start with synchronize_rcu() but both you and Michael raise some
> concern.
I've also idly wondered if calling synchronize_rcu() under the various
mm locks is a deadlock situation.
> Then I try spinlock and mutex:
>
> 1) spinlock: add lots of overhead on datapath, this leads 0 performance
> improvement.
I think the topic here is correctness not performance improvement
> 2) SRCU: full memory barrier requires on srcu_read_lock(), which still leads
> little performance improvement
> 3) mutex: a possible issue is need to wait for the page to be swapped in (is
> this unacceptable ?), another issue is that we need hold vq lock during
> range overlap check.
I have a feeling that mmu notififers cannot safely become dependent on
progress of swap without causing deadlock. You probably should avoid
this.
> > And, again, you can't re-invent a spinlock with open coding and get
> > something better.
>
> So the question is if waiting for swap is considered to be unsuitable for
> MMU notifiers. If not, it would simplify codes. If not, we still need to
> figure out a possible solution.
>
> Btw, I come up another idea, that is to disable preemption when vhost thread
> need to access the memory. Then register preempt notifier and if vhost
> thread is preempted, we're sure no one will access the memory and can do the
> cleanup.
I think you should use the spinlock so at least the code is obviously
functionally correct and worry about designing some properly justified
performance change after.
Jason
^ permalink raw reply
* Re: [PATCH 00/34] put_user_pages(): miscellaneous call sites
From: Jan Kara @ 2019-08-02 12:41 UTC (permalink / raw)
To: Michal Hocko
Cc: john.hubbard, Andrew Morton, Christoph Hellwig, Dan Williams,
Dave Chinner, Dave Hansen, Ira Weiny, Jan Kara, Jason Gunthorpe,
Jérôme Glisse, LKML, amd-gfx, ceph-devel, devel, devel,
dri-devel, intel-gfx, kvm, linux-arm-kernel, linux-block,
linux-crypto, linux-fbdev, linux-fsdevel, linux-media, linux-mm,
linux-nfs, linux-rdma, linux-rpi-kernel, linux-xfs, netdev,
rds-devel, sparclinux, x86, xen-devel, John Hubbard
In-Reply-To: <20190802091244.GD6461@dhcp22.suse.cz>
On Fri 02-08-19 11:12:44, Michal Hocko wrote:
> On Thu 01-08-19 19:19:31, john.hubbard@gmail.com wrote:
> [...]
> > 2) Convert all of the call sites for get_user_pages*(), to
> > invoke put_user_page*(), instead of put_page(). This involves dozens of
> > call sites, and will take some time.
>
> How do we make sure this is the case and it will remain the case in the
> future? There must be some automagic to enforce/check that. It is simply
> not manageable to do it every now and then because then 3) will simply
> be never safe.
>
> Have you considered coccinele or some other scripted way to do the
> transition? I have no idea how to deal with future changes that would
> break the balance though.
Yeah, that's why I've been suggesting at LSF/MM that we may need to create
a gup wrapper - say vaddr_pin_pages() - and track which sites dropping
references got converted by using this wrapper instead of gup. The
counterpart would then be more logically named as unpin_page() or whatever
instead of put_user_page(). Sure this is not completely foolproof (you can
create new callsite using vaddr_pin_pages() and then just drop refs using
put_page()) but I suppose it would be a high enough barrier for missed
conversions... Thoughts?
Honza
--
Jan Kara <jack@suse.com>
SUSE Labs, CR
^ permalink raw reply
* Re: memory leak in tipc_group_create_member
From: Ying Xue @ 2019-08-02 12:18 UTC (permalink / raw)
To: Hillf Danton, syzbot
Cc: davem, jon.maloy, linux-kernel, netdev, syzkaller-bugs,
tipc-discussion
In-Reply-To: <000000000000879057058f193fb5@google.com>
On 8/2/19 3:44 PM, Hillf Danton wrote:
>
> On Thu, 01 Aug 2019 19:38:06 -0700
>> Hello,
>>
>> syzbot found the following crash on:
>>
>> HEAD commit: a9815a4f Merge branch 'x86-urgent-for-linus' of git://git...
>> git tree: upstream
>> console output: https://syzkaller.appspot.com/x/log.txt?x=12a6dbf0600000
>> kernel config: https://syzkaller.appspot.com/x/.config?x=37c48fb52e3789e6
>> dashboard link: https://syzkaller.appspot.com/bug?extid=f95d90c454864b3b5bc9
>> compiler: gcc (GCC) 9.0.0 20181231 (experimental)
>> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=13be3ecc600000
>> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=11c992b4600000
>>
>> IMPORTANT: if you fix the bug, please add the following tag to the commit:
>> Reported-by: syzbot+f95d90c454864b3b5bc9@syzkaller.appspotmail.com
>>
>> executing program
>> BUG: memory leak
>> unreferenced object 0xffff888122bca200 (size 128):
>> comm "syz-executor232", pid 7065, jiffies 4294943817 (age 8.880s)
>> 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 18 a2 bc 22 81 88 ff ff ..........."....
>> backtrace:
>> [<000000005bada299>] kmemleak_alloc_recursive include/linux/kmemleak.h:43 [inline]
>> [<000000005bada299>] slab_post_alloc_hook mm/slab.h:522 [inline]
>> [<000000005bada299>] slab_alloc mm/slab.c:3319 [inline]
>> [<000000005bada299>] kmem_cache_alloc_trace+0x145/0x2c0 mm/slab.c:3548
>> [<00000000e7bcdc9f>] kmalloc include/linux/slab.h:552 [inline]
>> [<00000000e7bcdc9f>] kzalloc include/linux/slab.h:748 [inline]
>> [<00000000e7bcdc9f>] tipc_group_create_member+0x3c/0x190 net/tipc/group.c:306
>> [<0000000005f56f40>] tipc_group_add_member+0x34/0x40 net/tipc/group.c:327
>> [<0000000044406683>] tipc_nametbl_build_group+0x9b/0xf0 net/tipc/name_table.c:600
>> [<000000009f71e803>] tipc_sk_join net/tipc/socket.c:2901 [inline]
>> [<000000009f71e803>] tipc_setsockopt+0x170/0x490 net/tipc/socket.c:3006
>> [<000000007f61cbc2>] __sys_setsockopt+0x10f/0x220 net/socket.c:2084
>> [<00000000cc630372>] __do_sys_setsockopt net/socket.c:2100 [inline]
>> [<00000000cc630372>] __se_sys_setsockopt net/socket.c:2097 [inline]
>> [<00000000cc630372>] __x64_sys_setsockopt+0x26/0x30 net/socket.c:2097
>> [<00000000ec30be33>] do_syscall_64+0x76/0x1a0 arch/x86/entry/common.c:296
>> [<00000000271be3e6>] entry_SYSCALL_64_after_hwframe+0x44/0xa9
>>
Acked-by: Ying Xue <ying.xue@windriver.com>
>
> --- a/net/tipc/group.c
> +++ b/net/tipc/group.c
> @@ -273,7 +273,7 @@ static struct tipc_member *tipc_group_fi
> return NULL;
> }
>
> -static void tipc_group_add_to_tree(struct tipc_group *grp,
> +static struct tipc_member *tipc_group_add_to_tree(struct tipc_group *grp,
> struct tipc_member *m)
> {
> u64 nkey, key = (u64)m->node << 32 | m->port;
> @@ -282,7 +282,6 @@ static void tipc_group_add_to_tree(struc
>
> n = &grp->members.rb_node;
> while (*n) {
> - tmp = container_of(*n, struct tipc_member, tree_node);
> parent = *n;
> tmp = container_of(parent, struct tipc_member, tree_node);
> nkey = (u64)tmp->node << 32 | tmp->port;
> @@ -291,17 +290,18 @@ static void tipc_group_add_to_tree(struc
> else if (key > nkey)
> n = &(*n)->rb_right;
> else
> - return;
> + return tmp;
> }
> rb_link_node(&m->tree_node, parent, n);
> rb_insert_color(&m->tree_node, &grp->members);
> + return m;
> }
>
> static struct tipc_member *tipc_group_create_member(struct tipc_group *grp,
> u32 node, u32 port,
> u32 instance, int state)
> {
> - struct tipc_member *m;
> + struct tipc_member *m, *n;
>
> m = kzalloc(sizeof(*m), GFP_ATOMIC);
> if (!m)
> @@ -315,10 +315,14 @@ static struct tipc_member *tipc_group_cr
> m->instance = instance;
> m->bc_acked = grp->bc_snd_nxt - 1;
> grp->member_cnt++;
> - tipc_group_add_to_tree(grp, m);
> - tipc_nlist_add(&grp->dests, m->node);
> - m->state = state;
> - return m;
> + n = tipc_group_add_to_tree(grp, m);
> + if (n == m) {
> + tipc_nlist_add(&grp->dests, m->node);
> + m->state = state;
> + } else {
> + kfree(m);
> + }
> + return n;
> }
>
> void tipc_group_add_member(struct tipc_group *grp, u32 node,
> --
>
>
^ permalink raw reply
* [PATCH 2/3] net/mlx5: Use refcount_() APIs
From: Chuhong Yuan @ 2019-08-02 12:10 UTC (permalink / raw)
Cc: Saeed Mahameed, Leon Romanovsky, David S . Miller, netdev,
linux-rdma, linux-kernel, Chuhong Yuan
This patch depends on PATCH 1/3.
After converting refcount to refcount_t, use
refcount_() APIs to operate it.
Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
---
drivers/net/ethernet/mellanox/mlx5/core/qp.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/qp.c b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
index b8ba74de9555..7b44d1e49604 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/qp.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/qp.c
@@ -53,7 +53,7 @@ mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
common = radix_tree_lookup(&table->tree, rsn);
if (common)
- atomic_inc(&common->refcount);
+ refcount_inc(&common->refcount);
spin_unlock_irqrestore(&table->lock, flags);
@@ -62,7 +62,7 @@ mlx5_get_rsc(struct mlx5_qp_table *table, u32 rsn)
void mlx5_core_put_rsc(struct mlx5_core_rsc_common *common)
{
- if (atomic_dec_and_test(&common->refcount))
+ if (refcount_dec_and_test(&common->refcount))
complete(&common->free);
}
@@ -209,7 +209,7 @@ static int create_resource_common(struct mlx5_core_dev *dev,
if (err)
return err;
- atomic_set(&qp->common.refcount, 1);
+ refcount_set(&qp->common.refcount, 1);
init_completion(&qp->common.free);
qp->pid = current->pid;
--
2.20.1
^ permalink raw reply related
* [PATCH 1/3] mlx5: Use refcount_t for refcount
From: Chuhong Yuan @ 2019-08-02 12:10 UTC (permalink / raw)
Cc: Leon Romanovsky, Saeed Mahameed, linux-rdma, netdev, linux-kernel,
Chuhong Yuan
refcount_t is better for reference counters since its
implementation can prevent overflows.
So convert atomic_t ref counters to refcount_t.
Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
---
include/linux/mlx5/driver.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h
index 0e6da1840c7d..ec8fb382d426 100644
--- a/include/linux/mlx5/driver.h
+++ b/include/linux/mlx5/driver.h
@@ -398,7 +398,7 @@ enum mlx5_res_type {
struct mlx5_core_rsc_common {
enum mlx5_res_type res;
- atomic_t refcount;
+ refcount_t refcount;
struct completion free;
};
--
2.20.1
^ permalink raw reply related
* [PATCH 0/3] Use refcount_t for refcount
From: Chuhong Yuan @ 2019-08-02 12:10 UTC (permalink / raw)
Cc: Leon Romanovsky, Saeed Mahameed, David S . Miller, Doug Ledford,
Jason Gunthorpe, linux-rdma, netdev, linux-kernel, Chuhong Yuan
Reference counters are preferred to use refcount_t instead of
atomic_t.
This is because the implementation of refcount_t can prevent
overflows and detect possible use-after-free.
First convert the refcount field to refcount_t in mlx5/driver.h.
Then convert the uses to refcount_() APIs.
Chuhong Yuan (3):
mlx5: Use refcount_t for refcount
net/mlx5: Use refcount_() APIs
IB/mlx5: Use refcount_() APIs
drivers/infiniband/hw/mlx5/srq_cmd.c | 6 +++---
drivers/net/ethernet/mellanox/mlx5/core/qp.c | 6 +++---
include/linux/mlx5/driver.h | 2 +-
3 files changed, 7 insertions(+), 7 deletions(-)
--
2.20.1
^ permalink raw reply
* [PATCH] net/mlx5e: Use refcount_t for refcount
From: Chuhong Yuan @ 2019-08-02 12:10 UTC (permalink / raw)
Cc: Saeed Mahameed, Leon Romanovsky, David S . Miller, netdev,
linux-rdma, linux-kernel, Chuhong Yuan
refcount_t is better for reference counters since its
implementation can prevent overflows.
So convert atomic_t ref counters to refcount_t.
Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
---
drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
index b9d4f4e19ff9..045e6564481f 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/vxlan.c
@@ -48,7 +48,7 @@ struct mlx5_vxlan {
struct mlx5_vxlan_port {
struct hlist_node hlist;
- atomic_t refcount;
+ refcount_t refcount;
u16 udp_port;
};
@@ -113,7 +113,7 @@ int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
vxlanp = mlx5_vxlan_lookup_port(vxlan, port);
if (vxlanp) {
- atomic_inc(&vxlanp->refcount);
+ refcount_inc(&vxlanp->refcount);
return 0;
}
@@ -137,7 +137,7 @@ int mlx5_vxlan_add_port(struct mlx5_vxlan *vxlan, u16 port)
}
vxlanp->udp_port = port;
- atomic_set(&vxlanp->refcount, 1);
+ refcount_set(&vxlanp->refcount, 1);
spin_lock_bh(&vxlan->lock);
hash_add(vxlan->htable, &vxlanp->hlist, port);
@@ -170,7 +170,7 @@ int mlx5_vxlan_del_port(struct mlx5_vxlan *vxlan, u16 port)
goto out_unlock;
}
- if (atomic_dec_and_test(&vxlanp->refcount)) {
+ if (refcount_dec_and_test(&vxlanp->refcount)) {
hash_del(&vxlanp->hlist);
remove = true;
}
--
2.20.1
^ permalink raw reply related
* [PATCH] net/mlx4_core: Use refcount_t for refcount
From: Chuhong Yuan @ 2019-08-02 12:10 UTC (permalink / raw)
Cc: Tariq Toukan, David S . Miller, netdev, linux-rdma, linux-kernel,
Chuhong Yuan
refcount_t is better for reference counters since its
implementation can prevent overflows.
So convert atomic_t ref counters to refcount_t.
Also convert refcount from 0-based to 1-based.
Signed-off-by: Chuhong Yuan <hslester96@gmail.com>
---
.../ethernet/mellanox/mlx4/resource_tracker.c | 90 +++++++++----------
1 file changed, 45 insertions(+), 45 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
index 4356f3a58002..d7e26935fd76 100644
--- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
+++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
@@ -114,7 +114,7 @@ struct res_qp {
struct list_head mcg_list;
spinlock_t mcg_spl;
int local_qpn;
- atomic_t ref_count;
+ refcount_t ref_count;
u32 qpc_flags;
/* saved qp params before VST enforcement in order to restore on VGT */
u8 sched_queue;
@@ -143,7 +143,7 @@ static inline const char *mtt_states_str(enum res_mtt_states state)
struct res_mtt {
struct res_common com;
int order;
- atomic_t ref_count;
+ refcount_t ref_count;
};
enum res_mpt_states {
@@ -179,7 +179,7 @@ enum res_cq_states {
struct res_cq {
struct res_common com;
struct res_mtt *mtt;
- atomic_t ref_count;
+ refcount_t ref_count;
};
enum res_srq_states {
@@ -192,7 +192,7 @@ struct res_srq {
struct res_common com;
struct res_mtt *mtt;
struct res_cq *cq;
- atomic_t ref_count;
+ refcount_t ref_count;
};
enum res_counter_states {
@@ -1050,7 +1050,7 @@ static struct res_common *alloc_qp_tr(int id)
ret->local_qpn = id;
INIT_LIST_HEAD(&ret->mcg_list);
spin_lock_init(&ret->mcg_spl);
- atomic_set(&ret->ref_count, 0);
+ refcount_set(&ret->ref_count, 1);
return &ret->com;
}
@@ -1066,7 +1066,7 @@ static struct res_common *alloc_mtt_tr(int id, int order)
ret->com.res_id = id;
ret->order = order;
ret->com.state = RES_MTT_ALLOCATED;
- atomic_set(&ret->ref_count, 0);
+ refcount_set(&ret->ref_count, 1);
return &ret->com;
}
@@ -1110,7 +1110,7 @@ static struct res_common *alloc_cq_tr(int id)
ret->com.res_id = id;
ret->com.state = RES_CQ_ALLOCATED;
- atomic_set(&ret->ref_count, 0);
+ refcount_set(&ret->ref_count, 1);
return &ret->com;
}
@@ -1125,7 +1125,7 @@ static struct res_common *alloc_srq_tr(int id)
ret->com.res_id = id;
ret->com.state = RES_SRQ_ALLOCATED;
- atomic_set(&ret->ref_count, 0);
+ refcount_set(&ret->ref_count, 1);
return &ret->com;
}
@@ -1325,10 +1325,10 @@ static int add_res_range(struct mlx4_dev *dev, int slave, u64 base, int count,
static int remove_qp_ok(struct res_qp *res)
{
- if (res->com.state == RES_QP_BUSY || atomic_read(&res->ref_count) ||
+ if (res->com.state == RES_QP_BUSY || refcount_read(&res->ref_count) != 1 ||
!list_empty(&res->mcg_list)) {
pr_err("resource tracker: fail to remove qp, state %d, ref_count %d\n",
- res->com.state, atomic_read(&res->ref_count));
+ res->com.state, refcount_read(&res->ref_count));
return -EBUSY;
} else if (res->com.state != RES_QP_RESERVED) {
return -EPERM;
@@ -1340,11 +1340,11 @@ static int remove_qp_ok(struct res_qp *res)
static int remove_mtt_ok(struct res_mtt *res, int order)
{
if (res->com.state == RES_MTT_BUSY ||
- atomic_read(&res->ref_count)) {
+ refcount_read(&res->ref_count) != 1) {
pr_devel("%s-%d: state %s, ref_count %d\n",
__func__, __LINE__,
mtt_states_str(res->com.state),
- atomic_read(&res->ref_count));
+ refcount_read(&res->ref_count));
return -EBUSY;
} else if (res->com.state != RES_MTT_ALLOCATED)
return -EPERM;
@@ -1675,7 +1675,7 @@ static int cq_res_start_move_to(struct mlx4_dev *dev, int slave, int cqn,
} else if (state == RES_CQ_ALLOCATED) {
if (r->com.state != RES_CQ_HW)
err = -EINVAL;
- else if (atomic_read(&r->ref_count))
+ else if (refcount_read(&r->ref_count) != 1)
err = -EBUSY;
else
err = 0;
@@ -1715,7 +1715,7 @@ static int srq_res_start_move_to(struct mlx4_dev *dev, int slave, int index,
} else if (state == RES_SRQ_ALLOCATED) {
if (r->com.state != RES_SRQ_HW)
err = -EINVAL;
- else if (atomic_read(&r->ref_count))
+ else if (refcount_read(&r->ref_count) != 1)
err = -EBUSY;
} else if (state != RES_SRQ_HW || r->com.state != RES_SRQ_ALLOCATED) {
err = -EINVAL;
@@ -2808,7 +2808,7 @@ int mlx4_SW2HW_MPT_wrapper(struct mlx4_dev *dev, int slave,
goto ex_put;
if (!phys) {
- atomic_inc(&mtt->ref_count);
+ refcount_inc(&mtt->ref_count);
put_res(dev, slave, mtt->com.res_id, RES_MTT);
}
@@ -2845,7 +2845,7 @@ int mlx4_HW2SW_MPT_wrapper(struct mlx4_dev *dev, int slave,
goto ex_abort;
if (mpt->mtt)
- atomic_dec(&mpt->mtt->ref_count);
+ refcount_dec(&mpt->mtt->ref_count);
res_end_move(dev, slave, RES_MPT, id);
return 0;
@@ -3007,18 +3007,18 @@ int mlx4_RST2INIT_QP_wrapper(struct mlx4_dev *dev, int slave,
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
if (err)
goto ex_put_srq;
- atomic_inc(&mtt->ref_count);
+ refcount_inc(&mtt->ref_count);
qp->mtt = mtt;
- atomic_inc(&rcq->ref_count);
+ refcount_inc(&rcq->ref_count);
qp->rcq = rcq;
- atomic_inc(&scq->ref_count);
+ refcount_inc(&scq->ref_count);
qp->scq = scq;
if (scqn != rcqn)
put_res(dev, slave, scqn, RES_CQ);
if (use_srq) {
- atomic_inc(&srq->ref_count);
+ refcount_inc(&srq->ref_count);
put_res(dev, slave, srqn, RES_SRQ);
qp->srq = srq;
}
@@ -3113,7 +3113,7 @@ int mlx4_SW2HW_EQ_wrapper(struct mlx4_dev *dev, int slave,
if (err)
goto out_put;
- atomic_inc(&mtt->ref_count);
+ refcount_inc(&mtt->ref_count);
eq->mtt = mtt;
put_res(dev, slave, mtt->com.res_id, RES_MTT);
res_end_move(dev, slave, RES_EQ, res_id);
@@ -3310,7 +3310,7 @@ int mlx4_HW2SW_EQ_wrapper(struct mlx4_dev *dev, int slave,
if (err)
goto ex_put;
- atomic_dec(&eq->mtt->ref_count);
+ refcount_dec(&eq->mtt->ref_count);
put_res(dev, slave, eq->mtt->com.res_id, RES_MTT);
res_end_move(dev, slave, RES_EQ, res_id);
rem_res_range(dev, slave, res_id, 1, RES_EQ, 0);
@@ -3445,7 +3445,7 @@ int mlx4_SW2HW_CQ_wrapper(struct mlx4_dev *dev, int slave,
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
if (err)
goto out_put;
- atomic_inc(&mtt->ref_count);
+ refcount_inc(&mtt->ref_count);
cq->mtt = mtt;
put_res(dev, slave, mtt->com.res_id, RES_MTT);
res_end_move(dev, slave, RES_CQ, cqn);
@@ -3474,7 +3474,7 @@ int mlx4_HW2SW_CQ_wrapper(struct mlx4_dev *dev, int slave,
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
if (err)
goto out_move;
- atomic_dec(&cq->mtt->ref_count);
+ refcount_dec(&cq->mtt->ref_count);
res_end_move(dev, slave, RES_CQ, cqn);
return 0;
@@ -3539,9 +3539,9 @@ static int handle_resize(struct mlx4_dev *dev, int slave,
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
if (err)
goto ex_put1;
- atomic_dec(&orig_mtt->ref_count);
+ refcount_dec(&orig_mtt->ref_count);
put_res(dev, slave, orig_mtt->com.res_id, RES_MTT);
- atomic_inc(&mtt->ref_count);
+ refcount_inc(&mtt->ref_count);
cq->mtt = mtt;
put_res(dev, slave, mtt->com.res_id, RES_MTT);
return 0;
@@ -3627,7 +3627,7 @@ int mlx4_SW2HW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
if (err)
goto ex_put_mtt;
- atomic_inc(&mtt->ref_count);
+ refcount_inc(&mtt->ref_count);
srq->mtt = mtt;
put_res(dev, slave, mtt->com.res_id, RES_MTT);
res_end_move(dev, slave, RES_SRQ, srqn);
@@ -3657,9 +3657,9 @@ int mlx4_HW2SW_SRQ_wrapper(struct mlx4_dev *dev, int slave,
err = mlx4_DMA_wrapper(dev, slave, vhcr, inbox, outbox, cmd);
if (err)
goto ex_abort;
- atomic_dec(&srq->mtt->ref_count);
+ refcount_dec(&srq->mtt->ref_count);
if (srq->cq)
- atomic_dec(&srq->cq->ref_count);
+ refcount_dec(&srq->cq->ref_count);
res_end_move(dev, slave, RES_SRQ, srqn);
return 0;
@@ -3988,11 +3988,11 @@ int mlx4_2RST_QP_wrapper(struct mlx4_dev *dev, int slave,
if (err)
goto ex_abort;
- atomic_dec(&qp->mtt->ref_count);
- atomic_dec(&qp->rcq->ref_count);
- atomic_dec(&qp->scq->ref_count);
+ refcount_dec(&qp->mtt->ref_count);
+ refcount_dec(&qp->rcq->ref_count);
+ refcount_dec(&qp->scq->ref_count);
if (qp->srq)
- atomic_dec(&qp->srq->ref_count);
+ refcount_dec(&qp->srq->ref_count);
res_end_move(dev, slave, RES_QP, qpn);
return 0;
@@ -4456,7 +4456,7 @@ int mlx4_QP_FLOW_STEERING_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
if (mlx4_is_bonded(dev))
mlx4_do_mirror_rule(dev, rrule);
- atomic_inc(&rqp->ref_count);
+ refcount_inc(&rqp->ref_count);
err_put_rule:
put_res(dev, slave, vhcr->out_param, RES_FS_RULE);
@@ -4540,7 +4540,7 @@ int mlx4_QP_FLOW_STEERING_DETACH_wrapper(struct mlx4_dev *dev, int slave,
MLX4_QP_FLOW_STEERING_DETACH, MLX4_CMD_TIME_CLASS_A,
MLX4_CMD_NATIVE);
if (!err)
- atomic_dec(&rqp->ref_count);
+ refcount_dec(&rqp->ref_count);
out:
put_res(dev, slave, qpn, RES_QP);
return err;
@@ -4702,11 +4702,11 @@ static void rem_slave_qps(struct mlx4_dev *dev, int slave)
if (err)
mlx4_dbg(dev, "rem_slave_qps: failed to move slave %d qpn %d to reset\n",
slave, qp->local_qpn);
- atomic_dec(&qp->rcq->ref_count);
- atomic_dec(&qp->scq->ref_count);
- atomic_dec(&qp->mtt->ref_count);
+ refcount_dec(&qp->rcq->ref_count);
+ refcount_dec(&qp->scq->ref_count);
+ refcount_dec(&qp->mtt->ref_count);
if (qp->srq)
- atomic_dec(&qp->srq->ref_count);
+ refcount_dec(&qp->srq->ref_count);
state = RES_QP_MAPPED;
break;
default:
@@ -4768,9 +4768,9 @@ static void rem_slave_srqs(struct mlx4_dev *dev, int slave)
mlx4_dbg(dev, "rem_slave_srqs: failed to move slave %d srq %d to SW ownership\n",
slave, srqn);
- atomic_dec(&srq->mtt->ref_count);
+ refcount_dec(&srq->mtt->ref_count);
if (srq->cq)
- atomic_dec(&srq->cq->ref_count);
+ refcount_dec(&srq->cq->ref_count);
state = RES_SRQ_ALLOCATED;
break;
@@ -4805,7 +4805,7 @@ static void rem_slave_cqs(struct mlx4_dev *dev, int slave)
spin_lock_irq(mlx4_tlock(dev));
list_for_each_entry_safe(cq, tmp, cq_list, com.list) {
spin_unlock_irq(mlx4_tlock(dev));
- if (cq->com.owner == slave && !atomic_read(&cq->ref_count)) {
+ if (cq->com.owner == slave && refcount_read(&cq->ref_count) == 1) {
cqn = cq->com.res_id;
state = cq->com.from_state;
while (state != 0) {
@@ -4832,7 +4832,7 @@ static void rem_slave_cqs(struct mlx4_dev *dev, int slave)
if (err)
mlx4_dbg(dev, "rem_slave_cqs: failed to move slave %d cq %d to SW ownership\n",
slave, cqn);
- atomic_dec(&cq->mtt->ref_count);
+ refcount_dec(&cq->mtt->ref_count);
state = RES_CQ_ALLOCATED;
break;
@@ -4900,7 +4900,7 @@ static void rem_slave_mrs(struct mlx4_dev *dev, int slave)
mlx4_dbg(dev, "rem_slave_mrs: failed to move slave %d mpt %d to SW ownership\n",
slave, mptn);
if (mpt->mtt)
- atomic_dec(&mpt->mtt->ref_count);
+ refcount_dec(&mpt->mtt->ref_count);
state = RES_MPT_MAPPED;
break;
default:
@@ -5144,7 +5144,7 @@ static void rem_slave_eqs(struct mlx4_dev *dev, int slave)
if (err)
mlx4_dbg(dev, "rem_slave_eqs: failed to move slave %d eqs %d to SW ownership\n",
slave, eqn & 0x3ff);
- atomic_dec(&eq->mtt->ref_count);
+ refcount_dec(&eq->mtt->ref_count);
state = RES_EQ_RESERVED;
break;
--
2.20.1
^ permalink raw reply related
* Re: [PATCH -next] iwlwifi: dbg: work around clang bug by marking debug strings static
From: Michael Ellerman @ 2019-08-02 12:04 UTC (permalink / raw)
To: Johannes Berg, Nick Desaulniers, kvalo, Luca Coelho
Cc: Arnd Bergmann, Nathan Chancellor, Emmanuel Grumbach,
Intel Linux Wireless, David S. Miller, Shahar S Matityahu,
Sara Sharon, linux-wireless, netdev, linux-kernel,
clang-built-linux
In-Reply-To: <3a2b6d4f9356d54ab8e83fbf25ba9c5f50181f0d.camel@sipsolutions.net>
Johannes Berg <johannes@sipsolutions.net> writes:
>> Luca, you said this was already fixed in your internal tree, and the fix
>> would appear soon in next, but I don't see anything in linux-next?
>
> Luca is still on vacation, but I just sent out a version of the patch we
> had applied internally.
Awesome, thanks.
cheers
^ permalink raw reply
* [PATCH 2/4] can: peak_usb: force the string buffer NULL-terminated
From: Marc Kleine-Budde @ 2019-08-02 12:00 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, Wang Xiayang, Marc Kleine-Budde
In-Reply-To: <20190802120038.18154-1-mkl@pengutronix.de>
From: Wang Xiayang <xywang.sjtu@sjtu.edu.cn>
strncpy() does not ensure NULL-termination when the input string size
equals to the destination buffer size IFNAMSIZ. The output string is
passed to dev_info() which relies on the NULL-termination.
Use strlcpy() instead.
This issue is identified by a Coccinelle script.
Signed-off-by: Wang Xiayang <xywang.sjtu@sjtu.edu.cn>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index 22b9c8e6d040..65dce642b86b 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -855,7 +855,7 @@ static void peak_usb_disconnect(struct usb_interface *intf)
dev_prev_siblings = dev->prev_siblings;
dev->state &= ~PCAN_USB_STATE_CONNECTED;
- strncpy(name, netdev->name, IFNAMSIZ);
+ strlcpy(name, netdev->name, IFNAMSIZ);
unregister_netdev(netdev);
--
2.20.1
^ permalink raw reply related
* [PATCH 1/4] can: sja1000: force the string buffer NULL-terminated
From: Marc Kleine-Budde @ 2019-08-02 12:00 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel, Wang Xiayang, Marc Kleine-Budde
In-Reply-To: <20190802120038.18154-1-mkl@pengutronix.de>
From: Wang Xiayang <xywang.sjtu@sjtu.edu.cn>
strncpy() does not ensure NULL-termination when the input string size
equals to the destination buffer size IFNAMSIZ. The output string
'name' is passed to dev_info which relies on NULL-termination.
Use strlcpy() instead.
This issue is identified by a Coccinelle script.
Signed-off-by: Wang Xiayang <xywang.sjtu@sjtu.edu.cn>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/sja1000/peak_pcmcia.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/sja1000/peak_pcmcia.c b/drivers/net/can/sja1000/peak_pcmcia.c
index 185c7f7d38a4..5e0d5e8101c8 100644
--- a/drivers/net/can/sja1000/peak_pcmcia.c
+++ b/drivers/net/can/sja1000/peak_pcmcia.c
@@ -479,7 +479,7 @@ static void pcan_free_channels(struct pcan_pccard *card)
if (!netdev)
continue;
- strncpy(name, netdev->name, IFNAMSIZ);
+ strlcpy(name, netdev->name, IFNAMSIZ);
unregister_sja1000dev(netdev);
--
2.20.1
^ permalink raw reply related
* [PATCH 4/4] can: peak_usb: pcan_usb_pro: Fix info-leaks to USB devices
From: Marc Kleine-Budde @ 2019-08-02 12:00 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Tomas Bortoli,
syzbot+d6a5a1a3657b596ef132, linux-stable, Marc Kleine-Budde
In-Reply-To: <20190802120038.18154-1-mkl@pengutronix.de>
From: Tomas Bortoli <tomasbortoli@gmail.com>
Uninitialized Kernel memory can leak to USB devices.
Fix by using kzalloc() instead of kmalloc() on the affected buffers.
Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com>
Reported-by: syzbot+d6a5a1a3657b596ef132@syzkaller.appspotmail.com
Fixes: f14e22435a27 ("net: can: peak_usb: Do not do dma on the stack")
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
index 178bb7cff0c1..53cb2f72bdd0 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_pro.c
@@ -494,7 +494,7 @@ static int pcan_usb_pro_drv_loaded(struct peak_usb_device *dev, int loaded)
u8 *buffer;
int err;
- buffer = kmalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
+ buffer = kzalloc(PCAN_USBPRO_FCT_DRVLD_REQ_LEN, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
--
2.20.1
^ permalink raw reply related
* [PATCH 3/4] can: peak_usb: pcan_usb_fd: uix info-leaks to USB devices
From: Marc Kleine-Budde @ 2019-08-02 12:00 UTC (permalink / raw)
To: netdev
Cc: davem, linux-can, kernel, Tomas Bortoli,
syzbot+513e4d0985298538bf9b, linux-stable, Marc Kleine-Budde
In-Reply-To: <20190802120038.18154-1-mkl@pengutronix.de>
From: Tomas Bortoli <tomasbortoli@gmail.com>
Uninitialized Kernel memory can leak to USB devices.
Fix by using kzalloc() instead of kmalloc() on the affected buffers.
Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com>
Reported-by: syzbot+513e4d0985298538bf9b@syzkaller.appspotmail.com
Fixes: 0a25e1f4f185 ("can: peak_usb: add support for PEAK new CANFD USB adapters")
Cc: linux-stable <stable@vger.kernel.org>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
---
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
index 34761c3a6286..47cc1ff5b88e 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_fd.c
@@ -841,7 +841,7 @@ static int pcan_usb_fd_init(struct peak_usb_device *dev)
goto err_out;
/* allocate command buffer once for all for the interface */
- pdev->cmd_buffer_addr = kmalloc(PCAN_UFD_CMD_BUFFER_SIZE,
+ pdev->cmd_buffer_addr = kzalloc(PCAN_UFD_CMD_BUFFER_SIZE,
GFP_KERNEL);
if (!pdev->cmd_buffer_addr)
goto err_out_1;
--
2.20.1
^ permalink raw reply related
* pull-request: can 2019-08-02
From: Marc Kleine-Budde @ 2019-08-02 12:00 UTC (permalink / raw)
To: netdev; +Cc: davem, linux-can, kernel
Hello David,
this is a pull request of 4 patches for net/master.
The first two patches are by Wang Xiayang, they force that the string buffer
during a dev_info() is properly NULL terminated.
The last two patches are by Tomas Bortoli and fix both a potential info leak of
kernel memory to USB devices.
regards,
Marc
---
The following changes since commit 224c04973db1125fcebefffd86115f99f50f8277:
net: usb: pegasus: fix improper read if get_registers() fail (2019-08-01 18:18:27 -0400)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can.git tags/linux-can-fixes-for-5.3-20190802
for you to fetch changes up to ead16e53c2f0ed946d82d4037c630e2f60f4ab69:
can: peak_usb: pcan_usb_pro: Fix info-leaks to USB devices (2019-08-02 13:58:01 +0200)
----------------------------------------------------------------
linux-can-fixes-for-5.3-20190802
----------------------------------------------------------------
Tomas Bortoli (2):
can: peak_usb: pcan_usb_fd: Fix info-leaks to USB devices
can: peak_usb: pcan_usb_pro: Fix info-leaks to USB devices
Wang Xiayang (2):
can: sja1000: force the string buffer NULL-terminated
can: peak_usb: force the string buffer NULL-terminated
drivers/net/can/sja1000/peak_pcmcia.c | 2 +-
drivers/net/can/usb/peak_usb/pcan_usb_core.c | 2 +-
drivers/net/can/usb/peak_usb/pcan_usb_fd.c | 2 +-
drivers/net/can/usb/peak_usb/pcan_usb_pro.c | 2 +-
4 files changed, 4 insertions(+), 4 deletions(-)
^ permalink raw reply
* Re: [PATCH] peak_usb: Fix info-leaks to USB devices
From: Marc Kleine-Budde @ 2019-08-02 11:45 UTC (permalink / raw)
To: Tomas Bortoli, wg, linux-can
Cc: davem, gregkh, alexios.zavras, tglx, allison, netdev,
linux-kernel, syzkaller
In-Reply-To: <20190731145447.29270-1-tomasbortoli@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 766 bytes --]
On 7/31/19 4:54 PM, Tomas Bortoli wrote:
> Uninitialized Kernel memory can leak to USB devices.
>
> Fix by using kzalloc() instead of kmalloc() on the affected buffers.
>
> Signed-off-by: Tomas Bortoli <tomasbortoli@gmail.com>
> Reported-by: syzbot+d6a5a1a3657b596ef132@syzkaller.appspotmail.com
> Reported-by: syzbot+513e4d0985298538bf9b@syzkaller.appspotmail.com
Applied, but split into two patches, as the problem was introduced in
two separate commits.
regards,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* RE: [PATCH][net-next] net/mlx5: remove self-assignment on esw->dev
From: Parav Pandit @ 2019-08-02 11:31 UTC (permalink / raw)
To: Colin King, Saeed Mahameed, Leon Romanovsky, David S . Miller,
netdev@vger.kernel.org, linux-rdma@vger.kernel.org
Cc: kernel-janitors@vger.kernel.org, linux-kernel@vger.kernel.org
In-Reply-To: <20190802102223.26198-1-colin.king@canonical.com>
> -----Original Message-----
> From: linux-rdma-owner@vger.kernel.org <linux-rdma-
> owner@vger.kernel.org> On Behalf Of Colin King
> Sent: Friday, August 2, 2019 3:52 PM
> To: Saeed Mahameed <saeedm@mellanox.com>; Leon Romanovsky
> <leon@kernel.org>; David S . Miller <davem@davemloft.net>;
> netdev@vger.kernel.org; linux-rdma@vger.kernel.org
> Cc: kernel-janitors@vger.kernel.org; linux-kernel@vger.kernel.org
> Subject: [PATCH][net-next] net/mlx5: remove self-assignment on esw->dev
>
> From: Colin Ian King <colin.king@canonical.com>
>
> There is a self assignment of esw->dev to itself, clean this up by removing it.
>
> Addresses-Coverity: ("Self assignment")
> Fixes: 6cedde451399 ("net/mlx5: E-Switch, Verify support QoS element type")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
> ---
> drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
> b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
> index f4ace5f8e884..de0894b695e3 100644
> --- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
> +++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
> @@ -1413,7 +1413,7 @@ static int esw_vport_egress_config(struct
> mlx5_eswitch *esw,
>
> static bool element_type_supported(struct mlx5_eswitch *esw, int type) {
Making it const struct mlx5_eswitch *esw brings improves code hygiene further in such functions.
> - struct mlx5_core_dev *dev = esw->dev = esw->dev;
> + struct mlx5_core_dev *dev = esw->dev;
>
> switch (type) {
> case SCHEDULING_CONTEXT_ELEMENT_TYPE_TSAR:
> --
> 2.20.1
^ permalink raw reply
* Re: [PATCH 05/14] gpio: lpc32xx: allow building on non-lpc32xx targets
From: Arnd Bergmann @ 2019-08-02 11:19 UTC (permalink / raw)
To: Bartosz Golaszewski
Cc: soc, arm-soc, Vladimir Zapolskiy, Sylvain Lemieux, Russell King,
Gregory Clement, Linus Walleij, Jason Cooper, Andrew Lunn,
Sebastian Hesselbarth, David S. Miller, Greg Kroah-Hartman,
Alan Stern, Guenter Roeck, linux-gpio, netdev, linux-serial,
USB list, LINUXWATCHDOG, Lee Jones, LKML
In-Reply-To: <CAMpxmJWFfT_vrDas2fzW5tnxskk9kmgHQpGnGQ-_C20UaS_jhA@mail.gmail.com>
On Fri, Aug 2, 2019 at 9:10 AM Bartosz Golaszewski
<bgolaszewski@baylibre.com> wrote:
> > -#include <mach/hardware.h>
> > -#include <mach/platform.h>
> > +#define _GPREG(x) (x)
>
> What purpose does this macro serve?
>
> >
> > #define LPC32XX_GPIO_P3_INP_STATE _GPREG(0x000)
> > #define LPC32XX_GPIO_P3_OUTP_SET _GPREG(0x004)
In the existing code base, this macro converts a register offset to
an __iomem pointer for a gpio register. I changed the definition of the
macro here to keep the number of changes down, but I it's just
as easy to remove it if you prefer.
> > @@ -167,14 +166,26 @@ struct lpc32xx_gpio_chip {
> > struct gpio_regs *gpio_grp;
> > };
> >
> > +void __iomem *gpio_reg_base;
>
> Any reason why this can't be made part of struct lpc32xx_gpio_chip?
It could be, but it's the same for each instance, and not known until
probe() time, so the same pointer would need to be copied into each
instance that is otherwise read-only.
Let me know if you'd prefer me to rework these two things or leave
them as they are.
> > +static inline u32 gpreg_read(unsigned long offset)
>
> Here and elsewhere: could you please keep the lpc32xx_gpio prefix for
> all symbols?
Sure.
Arnd
^ permalink raw reply
* Re: [PATCH iproute2-next] ip tunnel: add json output
From: Andrea Claudi @ 2019-08-02 11:14 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: linux-netdev, David Ahern
In-Reply-To: <20190801081620.6b25d23c@hermes.lan>
On Thu, Aug 1, 2019 at 5:16 PM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> On Thu, 1 Aug 2019 12:12:58 +0200
> Andrea Claudi <aclaudi@redhat.com> wrote:
>
> > Add json support on iptunnel and ip6tunnel.
> > The plain text output format should remain the same.
> >
> > Signed-off-by: Andrea Claudi <aclaudi@redhat.com>
> > ---
> > ip/ip6tunnel.c | 82 +++++++++++++++++++++++++++++++--------------
> > ip/iptunnel.c | 90 +++++++++++++++++++++++++++++++++-----------------
> > ip/tunnel.c | 42 +++++++++++++++++------
> > 3 files changed, 148 insertions(+), 66 deletions(-)
> >
> > diff --git a/ip/ip6tunnel.c b/ip/ip6tunnel.c
> > index d7684a673fdc4..f2b9710c1320f 100644
> > --- a/ip/ip6tunnel.c
> > +++ b/ip/ip6tunnel.c
> > @@ -71,57 +71,90 @@ static void usage(void)
> > static void print_tunnel(const void *t)
> > {
> > const struct ip6_tnl_parm2 *p = t;
> > - char s1[1024];
> > - char s2[1024];
> > + SPRINT_BUF(b1);
> >
> > /* Do not use format_host() for local addr,
> > * symbolic name will not be useful.
> > */
> > - printf("%s: %s/ipv6 remote %s local %s",
> > - p->name,
> > - tnl_strproto(p->proto),
> > - format_host_r(AF_INET6, 16, &p->raddr, s1, sizeof(s1)),
> > - rt_addr_n2a_r(AF_INET6, 16, &p->laddr, s2, sizeof(s2)));
> > + open_json_object(NULL);
> > + print_string(PRINT_ANY, "ifname", "%s: ", p->name);
>
> Print this using color for interface name?
Thanks for the suggestion, I can do the same also for remote and local
addresses?
>
>
> > + snprintf(b1, sizeof(b1), "%s/ipv6", tnl_strproto(p->proto));
> > + print_string(PRINT_ANY, "mode", "%s ", b1);
> > + print_string(PRINT_ANY,
> > + "remote",
> > + "remote %s ",
> > + format_host_r(AF_INET6, 16, &p->raddr, b1, sizeof(b1)));
> > + print_string(PRINT_ANY,
> > + "local",
> > + "local %s",
> > + rt_addr_n2a_r(AF_INET6, 16, &p->laddr, b1, sizeof(b1)));
> > +
> > if (p->link) {
> > const char *n = ll_index_to_name(p->link);
> >
> > if (n)
> > - printf(" dev %s", n);
> > + print_string(PRINT_ANY, "link", " dev %s", n);
> > }
> >
> > if (p->flags & IP6_TNL_F_IGN_ENCAP_LIMIT)
> > - printf(" encaplimit none");
> > + print_bool(PRINT_ANY,
> > + "ip6_tnl_f_ign_encap_limit",
> > + " encaplimit none",
> > + true);
>
> For flags like this, print_null is more typical JSON than a boolean
> value. Null is better for presence flag. Bool is better if both true and
> false are printed.
Using print_null json JSON output becomes:
{
"ifname": "gre2",
"mode": "gre/ipv6",
"remote": "fd::1",
"local": "::",
"ip6_tnl_f_ign_encap_limit": null,
"hoplimit": 64,
"tclass": "0x00",
"flowlabel": "0x00000",
"flowinfo": "0x00000000",
"flags": []
}
Which seems a bit confusing to me (what does the "null" value means?).
Using print_null we also introduce an inconsistency with the JSON
output of ip/link_gre6.c and ip/link_ip6tnl.c.
I would prefer to use print_bool and print out
ip6_tnl_f_ign_encap_limit both when true and false, patching both
files above to do the same. WDYT?
^ permalink raw reply
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