| From foo@baz Wed Dec 2 10:40:54 AM CET 2020 |
| From: Parav Pandit <parav@nvidia.com> |
| Date: Wed, 25 Nov 2020 11:16:19 +0200 |
| Subject: devlink: Hold rtnl lock while reading netdev attributes |
| |
| From: Parav Pandit <parav@nvidia.com> |
| |
| [ Upstream commit b187c9b4178b87954dbc94e78a7094715794714f ] |
| |
| A netdevice of a devlink port can be moved to different net namespace |
| than its parent devlink instance. |
| This scenario occurs when devlink reload is not used. |
| |
| When netdevice is undergoing migration to net namespace, its ifindex |
| and name may change. |
| |
| In such use case, devlink port query may read stale netdev attributes. |
| |
| Fix it by reading them under rtnl lock. |
| |
| Fixes: bfcd3a466172 ("Introduce devlink infrastructure") |
| Signed-off-by: Parav Pandit <parav@nvidia.com> |
| Signed-off-by: Jakub Kicinski <kuba@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| net/core/devlink.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/net/core/devlink.c |
| +++ b/net/core/devlink.c |
| @@ -616,6 +616,8 @@ static int devlink_nl_port_fill(struct s |
| if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index)) |
| goto nla_put_failure; |
| |
| + /* Hold rtnl lock while accessing port's netdev attributes. */ |
| + rtnl_lock(); |
| spin_lock_bh(&devlink_port->type_lock); |
| if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type)) |
| goto nla_put_failure_type_locked; |
| @@ -642,6 +644,7 @@ static int devlink_nl_port_fill(struct s |
| goto nla_put_failure_type_locked; |
| } |
| spin_unlock_bh(&devlink_port->type_lock); |
| + rtnl_unlock(); |
| if (devlink_nl_port_attrs_put(msg, devlink_port)) |
| goto nla_put_failure; |
| if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack)) |
| @@ -652,6 +655,7 @@ static int devlink_nl_port_fill(struct s |
| |
| nla_put_failure_type_locked: |
| spin_unlock_bh(&devlink_port->type_lock); |
| + rtnl_unlock(); |
| nla_put_failure: |
| genlmsg_cancel(msg, hdr); |
| return -EMSGSIZE; |