lkml.org 
[lkml]   [2022]   [Aug]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.15 085/136] net: Fix data-races around sysctl_devconf_inherit_init_net.
    Date
    From: Kuniyuki Iwashima <kuniyu@amazon.com>

    [ Upstream commit a5612ca10d1aa05624ebe72633e0c8c792970833 ]

    While reading sysctl_devconf_inherit_init_net, it can be changed
    concurrently. Thus, we need to add READ_ONCE() to its readers.

    Fixes: 856c395cfa63 ("net: introduce a knob to control whether to inherit devconf config")
    Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    include/linux/netdevice.h | 9 +++++++++
    net/ipv4/devinet.c | 16 ++++++++++------
    net/ipv6/addrconf.c | 5 ++---
    3 files changed, 21 insertions(+), 9 deletions(-)

    diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
    index f9ed41ca7ac6d..3b97438afe3e2 100644
    --- a/include/linux/netdevice.h
    +++ b/include/linux/netdevice.h
    @@ -636,6 +636,15 @@ static inline bool net_has_fallback_tunnels(const struct net *net)
    #endif
    }

    +static inline int net_inherit_devconf(void)
    +{
    +#if IS_ENABLED(CONFIG_SYSCTL)
    + return READ_ONCE(sysctl_devconf_inherit_init_net);
    +#else
    + return 0;
    +#endif
    +}
    +
    static inline int netdev_queue_numa_node_read(const struct netdev_queue *q)
    {
    #if defined(CONFIG_XPS) && defined(CONFIG_NUMA)
    diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
    index 4744c7839de53..9ac41ffdc6344 100644
    --- a/net/ipv4/devinet.c
    +++ b/net/ipv4/devinet.c
    @@ -2673,23 +2673,27 @@ static __net_init int devinet_init_net(struct net *net)
    #endif

    if (!net_eq(net, &init_net)) {
    - if (IS_ENABLED(CONFIG_SYSCTL) &&
    - sysctl_devconf_inherit_init_net == 3) {
    + switch (net_inherit_devconf()) {
    + case 3:
    /* copy from the current netns */
    memcpy(all, current->nsproxy->net_ns->ipv4.devconf_all,
    sizeof(ipv4_devconf));
    memcpy(dflt,
    current->nsproxy->net_ns->ipv4.devconf_dflt,
    sizeof(ipv4_devconf_dflt));
    - } else if (!IS_ENABLED(CONFIG_SYSCTL) ||
    - sysctl_devconf_inherit_init_net != 2) {
    - /* inherit == 0 or 1: copy from init_net */
    + break;
    + case 0:
    + case 1:
    + /* copy from init_net */
    memcpy(all, init_net.ipv4.devconf_all,
    sizeof(ipv4_devconf));
    memcpy(dflt, init_net.ipv4.devconf_dflt,
    sizeof(ipv4_devconf_dflt));
    + break;
    + case 2:
    + /* use compiled values */
    + break;
    }
    - /* else inherit == 2: use compiled values */
    }

    #ifdef CONFIG_SYSCTL
    diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
    index 6dcf034835ecd..8800987fdb402 100644
    --- a/net/ipv6/addrconf.c
    +++ b/net/ipv6/addrconf.c
    @@ -7128,9 +7128,8 @@ static int __net_init addrconf_init_net(struct net *net)
    if (!dflt)
    goto err_alloc_dflt;

    - if (IS_ENABLED(CONFIG_SYSCTL) &&
    - !net_eq(net, &init_net)) {
    - switch (sysctl_devconf_inherit_init_net) {
    + if (!net_eq(net, &init_net)) {
    + switch (net_inherit_devconf()) {
    case 1: /* copy from init_net */
    memcpy(all, init_net.ipv6.devconf_all,
    sizeof(ipv6_devconf));
    --
    2.35.1


    \
     
     \ /
      Last update: 2022-08-29 13:13    [W:4.235 / U:0.000 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site