* [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking
@ 2019-08-27 22:07 Bernard Metzler
2019-08-28 5:02 ` Leon Romanovsky
2019-08-28 9:35 ` Bernard Metzler
0 siblings, 2 replies; 7+ messages in thread
From: Bernard Metzler @ 2019-08-27 22:07 UTC (permalink / raw)
To: linux-rdma; +Cc: bvanassche, jgg, dledford, Bernard Metzler
Walking the address list of an inet6_dev requires
appropriate locking. Since the called function
siw_listen_address() may sleep, we have to use
rtnl_lock() instead of read_lock_bh().
Also introduces:
- sanity checks if we got a device from
in_dev_get() or in6_dev_get().
- skipping IPv6 addresses flagged IFA_F_TENTATIVE
or IFA_F_DEPRECATED
Reported-by: Bart Van Assche <bvanassche@acm.org>
Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
---
drivers/infiniband/sw/siw/siw_cm.c | 31 +++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
index 1db5ad3d9580..8c1931a57f4a 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -1962,6 +1962,10 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
struct sockaddr_in s_laddr, *s_raddr;
const struct in_ifaddr *ifa;
+ if (!in_dev) {
+ rv = -ENODEV;
+ goto out;
+ }
memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr));
s_raddr = (struct sockaddr_in *)&id->remote_addr;
@@ -1991,22 +1995,27 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr),
*s_raddr = &to_sockaddr_in6(id->remote_addr);
+ if (!in6_dev) {
+ rv = -ENODEV;
+ goto out;
+ }
siw_dbg(id->device,
"laddr %pI6:%d, raddr %pI6:%d\n",
&s_laddr->sin6_addr, ntohs(s_laddr->sin6_port),
&s_raddr->sin6_addr, ntohs(s_raddr->sin6_port));
- read_lock_bh(&in6_dev->lock);
+ rtnl_lock();
list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
- struct sockaddr_in6 bind_addr;
-
+ if (ifp->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
+ continue;
if (ipv6_addr_any(&s_laddr->sin6_addr) ||
ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) {
- bind_addr.sin6_family = AF_INET6;
- bind_addr.sin6_port = s_laddr->sin6_port;
- bind_addr.sin6_flowinfo = 0;
- bind_addr.sin6_addr = ifp->addr;
- bind_addr.sin6_scope_id = dev->ifindex;
+ struct sockaddr_in6 bind_addr = {
+ .sin6_family = AF_INET6,
+ .sin6_port = s_laddr->sin6_port,
+ .sin6_flowinfo = 0,
+ .sin6_addr = ifp->addr,
+ .sin6_scope_id = dev->ifindex };
rv = siw_listen_address(id, backlog,
(struct sockaddr *)&bind_addr,
@@ -2015,12 +2024,12 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
listeners++;
}
}
- read_unlock_bh(&in6_dev->lock);
-
+ rtnl_unlock();
in6_dev_put(in6_dev);
} else {
- return -EAFNOSUPPORT;
+ rv = -EAFNOSUPPORT;
}
+out:
if (listeners)
rv = 0;
else if (!rv)
--
2.17.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking
2019-08-27 22:07 [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking Bernard Metzler
@ 2019-08-28 5:02 ` Leon Romanovsky
2019-08-28 9:35 ` Bernard Metzler
1 sibling, 0 replies; 7+ messages in thread
From: Leon Romanovsky @ 2019-08-28 5:02 UTC (permalink / raw)
To: Bernard Metzler; +Cc: linux-rdma, bvanassche, jgg, dledford
On Wed, Aug 28, 2019 at 12:07:20AM +0200, Bernard Metzler wrote:
> Walking the address list of an inet6_dev requires
> appropriate locking. Since the called function
> siw_listen_address() may sleep, we have to use
> rtnl_lock() instead of read_lock_bh().
>
> Also introduces:
> - sanity checks if we got a device from
> in_dev_get() or in6_dev_get().
> - skipping IPv6 addresses flagged IFA_F_TENTATIVE
> or IFA_F_DEPRECATED
>
> Reported-by: Bart Van Assche <bvanassche@acm.org>
> Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
> Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
> ---
Bernand,
Can you please post changelog along your patches?
Thanks
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: Re: [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking
2019-08-27 22:07 [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking Bernard Metzler
2019-08-28 5:02 ` Leon Romanovsky
@ 2019-08-28 9:35 ` Bernard Metzler
1 sibling, 0 replies; 7+ messages in thread
From: Bernard Metzler @ 2019-08-28 9:35 UTC (permalink / raw)
To: Leon Romanovsky; +Cc: linux-rdma, bvanassche, jgg, dledford
-----"Leon Romanovsky" <leon@kernel.org> wrote: -----
>To: "Bernard Metzler" <bmt@zurich.ibm.com>
>From: "Leon Romanovsky" <leon@kernel.org>
>Date: 08/28/2019 07:03AM
>Cc: linux-rdma@vger.kernel.org, bvanassche@acm.org, jgg@ziepe.ca,
>dledford@redhat.com
>Subject: [EXTERNAL] Re: [PATCH v3] RDMA/siw: Fix IPv6 addr_list
>locking
>
>On Wed, Aug 28, 2019 at 12:07:20AM +0200, Bernard Metzler wrote:
>> Walking the address list of an inet6_dev requires
>> appropriate locking. Since the called function
>> siw_listen_address() may sleep, we have to use
>> rtnl_lock() instead of read_lock_bh().
>>
>> Also introduces:
>> - sanity checks if we got a device from
>> in_dev_get() or in6_dev_get().
>> - skipping IPv6 addresses flagged IFA_F_TENTATIVE
>> or IFA_F_DEPRECATED
>>
>> Reported-by: Bart Van Assche <bvanassche@acm.org>
>> Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
>> Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
>> ---
>
>Bernand,
>
>Can you please post changelog along your patches?
>
Hi Leon,
Thanks, yes. Let me further try getting it alright ;)
I'll re-post v3.
Sorry!
Bernard.
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking
2019-08-28 13:03 Bernard Metzler
@ 2019-08-28 14:38 ` Doug Ledford
0 siblings, 0 replies; 7+ messages in thread
From: Doug Ledford @ 2019-08-28 14:38 UTC (permalink / raw)
To: Bernard Metzler, linux-rdma; +Cc: bvanassche, jgg
[-- Attachment #1: Type: text/plain, Size: 696 bytes --]
On Wed, 2019-08-28 at 15:03 +0200, Bernard Metzler wrote:
> Walking the address list of an inet6_dev requires
> appropriate locking. Since the called function
> siw_listen_address() may sleep, we have to use
> rtnl_lock() instead of read_lock_bh().
>
> Also introduces sanity checks if we got a device
> from in_dev_get() or in6_dev_get().
>
> Reported-by: Bart Van Assche <bvanassche@acm.org>
> Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
> Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
Applied to for-rc, thanks.
--
Doug Ledford <dledford@redhat.com>
GPG KeyID: B826A3330E572FDD
Fingerprint = AE6B 1BDA 122B 23B4 265B 1274 B826 A333 0E57 2FDD
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking
@ 2019-08-28 13:03 Bernard Metzler
2019-08-28 14:38 ` Doug Ledford
0 siblings, 1 reply; 7+ messages in thread
From: Bernard Metzler @ 2019-08-28 13:03 UTC (permalink / raw)
To: linux-rdma; +Cc: bvanassche, jgg, dledford, Bernard Metzler
Walking the address list of an inet6_dev requires
appropriate locking. Since the called function
siw_listen_address() may sleep, we have to use
rtnl_lock() instead of read_lock_bh().
Also introduces sanity checks if we got a device
from in_dev_get() or in6_dev_get().
Reported-by: Bart Van Assche <bvanassche@acm.org>
Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
---
v2 -> v3:
- Use plain version of list_for_each_entry
in exchange of list_for_each_entry_rcu.
v1 -> v2:
- Remove rcu_read_lock()/_unlock().
- Add check for IFA_F_TENTATIVE and
IFA_F_DEPRECATED flags.
drivers/infiniband/sw/siw/siw_cm.c | 31 +++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
index 1db5ad3d9580..8c1931a57f4a 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -1962,6 +1962,10 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
struct sockaddr_in s_laddr, *s_raddr;
const struct in_ifaddr *ifa;
+ if (!in_dev) {
+ rv = -ENODEV;
+ goto out;
+ }
memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr));
s_raddr = (struct sockaddr_in *)&id->remote_addr;
@@ -1991,22 +1995,27 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr),
*s_raddr = &to_sockaddr_in6(id->remote_addr);
+ if (!in6_dev) {
+ rv = -ENODEV;
+ goto out;
+ }
siw_dbg(id->device,
"laddr %pI6:%d, raddr %pI6:%d\n",
&s_laddr->sin6_addr, ntohs(s_laddr->sin6_port),
&s_raddr->sin6_addr, ntohs(s_raddr->sin6_port));
- read_lock_bh(&in6_dev->lock);
+ rtnl_lock();
list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
- struct sockaddr_in6 bind_addr;
-
+ if (ifp->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
+ continue;
if (ipv6_addr_any(&s_laddr->sin6_addr) ||
ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) {
- bind_addr.sin6_family = AF_INET6;
- bind_addr.sin6_port = s_laddr->sin6_port;
- bind_addr.sin6_flowinfo = 0;
- bind_addr.sin6_addr = ifp->addr;
- bind_addr.sin6_scope_id = dev->ifindex;
+ struct sockaddr_in6 bind_addr = {
+ .sin6_family = AF_INET6,
+ .sin6_port = s_laddr->sin6_port,
+ .sin6_flowinfo = 0,
+ .sin6_addr = ifp->addr,
+ .sin6_scope_id = dev->ifindex };
rv = siw_listen_address(id, backlog,
(struct sockaddr *)&bind_addr,
@@ -2015,12 +2024,12 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
listeners++;
}
}
- read_unlock_bh(&in6_dev->lock);
-
+ rtnl_unlock();
in6_dev_put(in6_dev);
} else {
- return -EAFNOSUPPORT;
+ rv = -EAFNOSUPPORT;
}
+out:
if (listeners)
rv = 0;
else if (!rv)
--
2.17.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking
2019-08-28 9:38 Bernard Metzler
@ 2019-08-28 10:47 ` Leon Romanovsky
0 siblings, 0 replies; 7+ messages in thread
From: Leon Romanovsky @ 2019-08-28 10:47 UTC (permalink / raw)
To: Bernard Metzler; +Cc: linux-rdma, bvanassche, jgg, dledford
On Wed, Aug 28, 2019 at 11:38:41AM +0200, Bernard Metzler wrote:
> Walking the address list of an inet6_dev requires
> appropriate locking. Since the called function
> siw_listen_address() may sleep, we have to use
> rtnl_lock() instead of read_lock_bh().
>
> Also introduces sanity checks if we got a device
> from in_dev_get() or in6_dev_get().
>
> Changes from v2:
> - Use plain version of list_for_each_entry
> in exchange of list_for_each_entry_rcu.
>
> Changes from v1:
> - Remove rcu_read_lock()/_unlock().
> - Add check for IFA_F_TENTATIVE and
> IFA_F_DEPRECATED flags.
You need to add changelogs after "---" line, they will be trimmed
automatically while applying to git.
Latest example:
https://lore.kernel.org/linux-rdma/26ae8c4006cb31ee8c26fb821451d43732c7a35a.camel@redhat.com/T/#m75d9725823fd3f437298528c427dcfc3a0fe9050
Thanks
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking
@ 2019-08-28 9:38 Bernard Metzler
2019-08-28 10:47 ` Leon Romanovsky
0 siblings, 1 reply; 7+ messages in thread
From: Bernard Metzler @ 2019-08-28 9:38 UTC (permalink / raw)
To: linux-rdma; +Cc: bvanassche, jgg, dledford, Bernard Metzler
Walking the address list of an inet6_dev requires
appropriate locking. Since the called function
siw_listen_address() may sleep, we have to use
rtnl_lock() instead of read_lock_bh().
Also introduces sanity checks if we got a device
from in_dev_get() or in6_dev_get().
Changes from v2:
- Use plain version of list_for_each_entry
in exchange of list_for_each_entry_rcu.
Changes from v1:
- Remove rcu_read_lock()/_unlock().
- Add check for IFA_F_TENTATIVE and
IFA_F_DEPRECATED flags.
Reported-by: Bart Van Assche <bvanassche@acm.org>
Fixes: 6c52fdc244b5 ("rdma/siw: connection management")
Signed-off-by: Bernard Metzler <bmt@zurich.ibm.com>
---
drivers/infiniband/sw/siw/siw_cm.c | 31 +++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/drivers/infiniband/sw/siw/siw_cm.c b/drivers/infiniband/sw/siw/siw_cm.c
index 1db5ad3d9580..8c1931a57f4a 100644
--- a/drivers/infiniband/sw/siw/siw_cm.c
+++ b/drivers/infiniband/sw/siw/siw_cm.c
@@ -1962,6 +1962,10 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
struct sockaddr_in s_laddr, *s_raddr;
const struct in_ifaddr *ifa;
+ if (!in_dev) {
+ rv = -ENODEV;
+ goto out;
+ }
memcpy(&s_laddr, &id->local_addr, sizeof(s_laddr));
s_raddr = (struct sockaddr_in *)&id->remote_addr;
@@ -1991,22 +1995,27 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
struct sockaddr_in6 *s_laddr = &to_sockaddr_in6(id->local_addr),
*s_raddr = &to_sockaddr_in6(id->remote_addr);
+ if (!in6_dev) {
+ rv = -ENODEV;
+ goto out;
+ }
siw_dbg(id->device,
"laddr %pI6:%d, raddr %pI6:%d\n",
&s_laddr->sin6_addr, ntohs(s_laddr->sin6_port),
&s_raddr->sin6_addr, ntohs(s_raddr->sin6_port));
- read_lock_bh(&in6_dev->lock);
+ rtnl_lock();
list_for_each_entry(ifp, &in6_dev->addr_list, if_list) {
- struct sockaddr_in6 bind_addr;
-
+ if (ifp->flags & (IFA_F_TENTATIVE | IFA_F_DEPRECATED))
+ continue;
if (ipv6_addr_any(&s_laddr->sin6_addr) ||
ipv6_addr_equal(&s_laddr->sin6_addr, &ifp->addr)) {
- bind_addr.sin6_family = AF_INET6;
- bind_addr.sin6_port = s_laddr->sin6_port;
- bind_addr.sin6_flowinfo = 0;
- bind_addr.sin6_addr = ifp->addr;
- bind_addr.sin6_scope_id = dev->ifindex;
+ struct sockaddr_in6 bind_addr = {
+ .sin6_family = AF_INET6,
+ .sin6_port = s_laddr->sin6_port,
+ .sin6_flowinfo = 0,
+ .sin6_addr = ifp->addr,
+ .sin6_scope_id = dev->ifindex };
rv = siw_listen_address(id, backlog,
(struct sockaddr *)&bind_addr,
@@ -2015,12 +2024,12 @@ int siw_create_listen(struct iw_cm_id *id, int backlog)
listeners++;
}
}
- read_unlock_bh(&in6_dev->lock);
-
+ rtnl_unlock();
in6_dev_put(in6_dev);
} else {
- return -EAFNOSUPPORT;
+ rv = -EAFNOSUPPORT;
}
+out:
if (listeners)
rv = 0;
else if (!rv)
--
2.17.2
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2019-08-28 14:38 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-27 22:07 [PATCH v3] RDMA/siw: Fix IPv6 addr_list locking Bernard Metzler
2019-08-28 5:02 ` Leon Romanovsky
2019-08-28 9:35 ` Bernard Metzler
2019-08-28 9:38 Bernard Metzler
2019-08-28 10:47 ` Leon Romanovsky
2019-08-28 13:03 Bernard Metzler
2019-08-28 14:38 ` Doug Ledford
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.