diff mbox series

[net-next] netlink: correct nlmsg size for multicast notifications

Message ID 20241219132644.725161-1-yuyanghuang@google.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series [net-next] netlink: correct nlmsg size for multicast notifications | expand

Checks

Context Check Description
netdev/series_format success Single patches do not need cover letters
netdev/tree_selection success Clearly marked for net-next
netdev/ynl success Generated files up to date; no warnings/errors; no diff in generated;
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit success Errors and warnings before: 0 this patch: 0
netdev/build_tools success No tools touched, skip
netdev/cc_maintainers success CCed 8 of 8 maintainers
netdev/build_clang success Errors and warnings before: 2 this patch: 2
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success Fixes tag looks correct
netdev/build_allmodconfig_warn success Errors and warnings before: 6 this patch: 6
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 20 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 1 this patch: 1
netdev/source_inline success Was 0 now: 0

Commit Message

Yuyang Huang Dec. 19, 2024, 1:26 p.m. UTC
Corrected the netlink message size calculation for multicast group
join/leave notifications. The previous calculation did not account for
the inclusion of both IPv4/IPv6 addresses and ifa_cacheinfo in the
payload. This fix ensures that the allocated message size is
sufficient to hold all necessary information.

Fixes: 2c2b61d2138f ("netlink: add IGMP/MLD join/leave notifications")
Cc: Maciej Żenczykowski <maze@google.com>
Cc: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
---
 net/ipv4/igmp.c  | 4 +++-
 net/ipv6/mcast.c | 4 +++-
 2 files changed, 6 insertions(+), 2 deletions(-)

Comments

Eric Dumazet Dec. 19, 2024, 1:42 p.m. UTC | #1
On Thu, Dec 19, 2024 at 2:27 PM Yuyang Huang <yuyanghuang@google.com> wrote:
>
> Corrected the netlink message size calculation for multicast group
> join/leave notifications. The previous calculation did not account for
> the inclusion of both IPv4/IPv6 addresses and ifa_cacheinfo in the
> payload. This fix ensures that the allocated message size is
> sufficient to hold all necessary information.
>
> Fixes: 2c2b61d2138f ("netlink: add IGMP/MLD join/leave notifications")
> Cc: Maciej Żenczykowski <maze@google.com>
> Cc: Lorenzo Colitti <lorenzo@google.com>
> Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
> ---
>  net/ipv4/igmp.c  | 4 +++-
>  net/ipv6/mcast.c | 4 +++-
>  2 files changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
> index 8a370ef37d3f..4e2f1497f320 100644
> --- a/net/ipv4/igmp.c
> +++ b/net/ipv4/igmp.c
> @@ -1473,7 +1473,9 @@ static void inet_ifmcaddr_notify(struct net_device *dev,
>         int err = -ENOMEM;
>
>         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> -                       nla_total_size(sizeof(__be32)), GFP_ATOMIC);
> +                       nla_total_size(sizeof(__be32)) +
> +                       nla_total_size(sizeof(struct ifa_cacheinfo)),
> +                       GFP_ATOMIC);
>         if (!skb)
>                 goto error;
>
> diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> index 587831c148de..b7430f15d1fc 100644
> --- a/net/ipv6/mcast.c
> +++ b/net/ipv6/mcast.c
> @@ -920,7 +920,9 @@ static void inet6_ifmcaddr_notify(struct net_device *dev,
>         int err = -ENOMEM;
>
>         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> -                       nla_total_size(16), GFP_ATOMIC);
> +                       nla_total_size(16) +

While we are at it , can you use nla_total_size(sizeof(struct in6_addr))

inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
please remove it.
Squash the following in v2, thanks !

diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 2e2684886953d55140cd3d4a1e024b5218331a49..4da409bc45777f60fd37bdee541c61165a51d22c
100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -5239,7 +5239,6 @@ int inet6_fill_ifmcaddr(struct sk_buff *skb,
        nlmsg_end(skb, nlh);
        return 0;
 }
-EXPORT_SYMBOL(inet6_fill_ifmcaddr);

 static int inet6_fill_ifacaddr(struct sk_buff *skb,
                               const struct ifacaddr6 *ifaca,
Eric Dumazet Dec. 19, 2024, 1:47 p.m. UTC | #2
On Thu, Dec 19, 2024 at 2:42 PM Eric Dumazet <edumazet@google.com> wrote:
>
> On Thu, Dec 19, 2024 at 2:27 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> >
> > Corrected the netlink message size calculation for multicast group
> > join/leave notifications. The previous calculation did not account for
> > the inclusion of both IPv4/IPv6 addresses and ifa_cacheinfo in the
> > payload. This fix ensures that the allocated message size is
> > sufficient to hold all necessary information.
> >
> > Fixes: 2c2b61d2138f ("netlink: add IGMP/MLD join/leave notifications")
> > Cc: Maciej Żenczykowski <maze@google.com>
> > Cc: Lorenzo Colitti <lorenzo@google.com>
> > Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
> > ---
> >  net/ipv4/igmp.c  | 4 +++-
> >  net/ipv6/mcast.c | 4 +++-
> >  2 files changed, 6 insertions(+), 2 deletions(-)
> >
> > diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
> > index 8a370ef37d3f..4e2f1497f320 100644
> > --- a/net/ipv4/igmp.c
> > +++ b/net/ipv4/igmp.c
> > @@ -1473,7 +1473,9 @@ static void inet_ifmcaddr_notify(struct net_device *dev,
> >         int err = -ENOMEM;
> >
> >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > -                       nla_total_size(sizeof(__be32)), GFP_ATOMIC);
> > +                       nla_total_size(sizeof(__be32)) +
> > +                       nla_total_size(sizeof(struct ifa_cacheinfo)),
> > +                       GFP_ATOMIC);
> >         if (!skb)
> >                 goto error;
> >
> > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> > index 587831c148de..b7430f15d1fc 100644
> > --- a/net/ipv6/mcast.c
> > +++ b/net/ipv6/mcast.c
> > @@ -920,7 +920,9 @@ static void inet6_ifmcaddr_notify(struct net_device *dev,
> >         int err = -ENOMEM;
> >
> >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > -                       nla_total_size(16), GFP_ATOMIC);
> > +                       nla_total_size(16) +
>
> While we are at it , can you use nla_total_size(sizeof(struct in6_addr))
>
> inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> please remove it.
> Squash the following in v2, thanks !
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 2e2684886953d55140cd3d4a1e024b5218331a49..4da409bc45777f60fd37bdee541c61165a51d22c
> 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -5239,7 +5239,6 @@ int inet6_fill_ifmcaddr(struct sk_buff *skb,
>         nlmsg_end(skb, nlh);
>         return 0;
>  }
> -EXPORT_SYMBOL(inet6_fill_ifmcaddr);
>
>  static int inet6_fill_ifacaddr(struct sk_buff *skb,
>                                const struct ifacaddr6 *ifaca,

Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.

All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
thus can sleep under memory pressure.

Same remark for inet_ifmcaddr_notify()
Yuyang Huang Dec. 19, 2024, 2:31 p.m. UTC | #3
Hi Eric

Thanks for the prompt review feedback. I will adjust all the comments
in the v2 patch.

>inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
please remove it.

I  made the same mistake in Link:
https://lore.kernel.org/netdev/20241218090057.76899-1-yuyanghuang@google.com/T/

I will fix that patch as well.

Thanks,
Yuyang

Thanks,
Yuyang


On Thu, Dec 19, 2024 at 10:47 PM Eric Dumazet <edumazet@google.com> wrote:
>
> On Thu, Dec 19, 2024 at 2:42 PM Eric Dumazet <edumazet@google.com> wrote:
> >
> > On Thu, Dec 19, 2024 at 2:27 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> > >
> > > Corrected the netlink message size calculation for multicast group
> > > join/leave notifications. The previous calculation did not account for
> > > the inclusion of both IPv4/IPv6 addresses and ifa_cacheinfo in the
> > > payload. This fix ensures that the allocated message size is
> > > sufficient to hold all necessary information.
> > >
> > > Fixes: 2c2b61d2138f ("netlink: add IGMP/MLD join/leave notifications")
> > > Cc: Maciej Żenczykowski <maze@google.com>
> > > Cc: Lorenzo Colitti <lorenzo@google.com>
> > > Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
> > > ---
> > >  net/ipv4/igmp.c  | 4 +++-
> > >  net/ipv6/mcast.c | 4 +++-
> > >  2 files changed, 6 insertions(+), 2 deletions(-)
> > >
> > > diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
> > > index 8a370ef37d3f..4e2f1497f320 100644
> > > --- a/net/ipv4/igmp.c
> > > +++ b/net/ipv4/igmp.c
> > > @@ -1473,7 +1473,9 @@ static void inet_ifmcaddr_notify(struct net_device *dev,
> > >         int err = -ENOMEM;
> > >
> > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > -                       nla_total_size(sizeof(__be32)), GFP_ATOMIC);
> > > +                       nla_total_size(sizeof(__be32)) +
> > > +                       nla_total_size(sizeof(struct ifa_cacheinfo)),
> > > +                       GFP_ATOMIC);
> > >         if (!skb)
> > >                 goto error;
> > >
> > > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> > > index 587831c148de..b7430f15d1fc 100644
> > > --- a/net/ipv6/mcast.c
> > > +++ b/net/ipv6/mcast.c
> > > @@ -920,7 +920,9 @@ static void inet6_ifmcaddr_notify(struct net_device *dev,
> > >         int err = -ENOMEM;
> > >
> > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > -                       nla_total_size(16), GFP_ATOMIC);
> > > +                       nla_total_size(16) +
> >
> > While we are at it , can you use nla_total_size(sizeof(struct in6_addr))
> >
> > inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> > please remove it.
> > Squash the following in v2, thanks !
> >
> > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> > index 2e2684886953d55140cd3d4a1e024b5218331a49..4da409bc45777f60fd37bdee541c61165a51d22c
> > 100644
> > --- a/net/ipv6/addrconf.c
> > +++ b/net/ipv6/addrconf.c
> > @@ -5239,7 +5239,6 @@ int inet6_fill_ifmcaddr(struct sk_buff *skb,
> >         nlmsg_end(skb, nlh);
> >         return 0;
> >  }
> > -EXPORT_SYMBOL(inet6_fill_ifmcaddr);
> >
> >  static int inet6_fill_ifacaddr(struct sk_buff *skb,
> >                                const struct ifacaddr6 *ifaca,
>
> Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.
>
> All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
> thus can sleep under memory pressure.
>
> Same remark for inet_ifmcaddr_notify()
Yuyang Huang Dec. 19, 2024, 3:27 p.m. UTC | #4
>Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.

>All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
>thus can sleep under memory pressure.

I might not have enough background knowledge here, but why does
holding RTNL imply that the callers are in process context?

Link: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/ipv6/addrconf.c#n2241

In addrconf.c, the logic joins the solicited-node multicast group and
calls into mcast.c logic, which eventually triggers the notification.
I guess this code path is not in process context when the kernel does
SLAAC?

Thanks,
Yuyang

On Thu, Dec 19, 2024 at 11:31 PM Yuyang Huang <yuyanghuang@google.com> wrote:
>
> Hi Eric
>
> Thanks for the prompt review feedback. I will adjust all the comments
> in the v2 patch.
>
> >inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> please remove it.
>
> I  made the same mistake in Link:
> https://lore.kernel.org/netdev/20241218090057.76899-1-yuyanghuang@google.com/T/
>
> I will fix that patch as well.
>
> Thanks,
> Yuyang
>
> Thanks,
> Yuyang
>
>
> On Thu, Dec 19, 2024 at 10:47 PM Eric Dumazet <edumazet@google.com> wrote:
> >
> > On Thu, Dec 19, 2024 at 2:42 PM Eric Dumazet <edumazet@google.com> wrote:
> > >
> > > On Thu, Dec 19, 2024 at 2:27 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> > > >
> > > > Corrected the netlink message size calculation for multicast group
> > > > join/leave notifications. The previous calculation did not account for
> > > > the inclusion of both IPv4/IPv6 addresses and ifa_cacheinfo in the
> > > > payload. This fix ensures that the allocated message size is
> > > > sufficient to hold all necessary information.
> > > >
> > > > Fixes: 2c2b61d2138f ("netlink: add IGMP/MLD join/leave notifications")
> > > > Cc: Maciej Żenczykowski <maze@google.com>
> > > > Cc: Lorenzo Colitti <lorenzo@google.com>
> > > > Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
> > > > ---
> > > >  net/ipv4/igmp.c  | 4 +++-
> > > >  net/ipv6/mcast.c | 4 +++-
> > > >  2 files changed, 6 insertions(+), 2 deletions(-)
> > > >
> > > > diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
> > > > index 8a370ef37d3f..4e2f1497f320 100644
> > > > --- a/net/ipv4/igmp.c
> > > > +++ b/net/ipv4/igmp.c
> > > > @@ -1473,7 +1473,9 @@ static void inet_ifmcaddr_notify(struct net_device *dev,
> > > >         int err = -ENOMEM;
> > > >
> > > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > > -                       nla_total_size(sizeof(__be32)), GFP_ATOMIC);
> > > > +                       nla_total_size(sizeof(__be32)) +
> > > > +                       nla_total_size(sizeof(struct ifa_cacheinfo)),
> > > > +                       GFP_ATOMIC);
> > > >         if (!skb)
> > > >                 goto error;
> > > >
> > > > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> > > > index 587831c148de..b7430f15d1fc 100644
> > > > --- a/net/ipv6/mcast.c
> > > > +++ b/net/ipv6/mcast.c
> > > > @@ -920,7 +920,9 @@ static void inet6_ifmcaddr_notify(struct net_device *dev,
> > > >         int err = -ENOMEM;
> > > >
> > > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > > -                       nla_total_size(16), GFP_ATOMIC);
> > > > +                       nla_total_size(16) +
> > >
> > > While we are at it , can you use nla_total_size(sizeof(struct in6_addr))
> > >
> > > inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> > > please remove it.
> > > Squash the following in v2, thanks !
> > >
> > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> > > index 2e2684886953d55140cd3d4a1e024b5218331a49..4da409bc45777f60fd37bdee541c61165a51d22c
> > > 100644
> > > --- a/net/ipv6/addrconf.c
> > > +++ b/net/ipv6/addrconf.c
> > > @@ -5239,7 +5239,6 @@ int inet6_fill_ifmcaddr(struct sk_buff *skb,
> > >         nlmsg_end(skb, nlh);
> > >         return 0;
> > >  }
> > > -EXPORT_SYMBOL(inet6_fill_ifmcaddr);
> > >
> > >  static int inet6_fill_ifacaddr(struct sk_buff *skb,
> > >                                const struct ifacaddr6 *ifaca,
> >
> > Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.
> >
> > All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
> > thus can sleep under memory pressure.
> >
> > Same remark for inet_ifmcaddr_notify()
Yuyang Huang Dec. 19, 2024, 3:34 p.m. UTC | #5
>Same remark for inet_ifmcaddr_notify()

Moreover, for both IPv4 and IPv6, when a device is up, the kernel
joins the all-hosts multicast addresses (224.0.0.1/ff02::1). I guess
this logic also does not run in process context?

Thanks,
Yuyang

On Fri, Dec 20, 2024 at 12:27 AM Yuyang Huang <yuyanghuang@google.com> wrote:
>
> >Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.
>
> >All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
> >thus can sleep under memory pressure.
>
> I might not have enough background knowledge here, but why does
> holding RTNL imply that the callers are in process context?
>
> Link: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/ipv6/addrconf.c#n2241
>
> In addrconf.c, the logic joins the solicited-node multicast group and
> calls into mcast.c logic, which eventually triggers the notification.
> I guess this code path is not in process context when the kernel does
> SLAAC?
>
> Thanks,
> Yuyang
>
> On Thu, Dec 19, 2024 at 11:31 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> >
> > Hi Eric
> >
> > Thanks for the prompt review feedback. I will adjust all the comments
> > in the v2 patch.
> >
> > >inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> > please remove it.
> >
> > I  made the same mistake in Link:
> > https://lore.kernel.org/netdev/20241218090057.76899-1-yuyanghuang@google.com/T/
> >
> > I will fix that patch as well.
> >
> > Thanks,
> > Yuyang
> >
> > Thanks,
> > Yuyang
> >
> >
> > On Thu, Dec 19, 2024 at 10:47 PM Eric Dumazet <edumazet@google.com> wrote:
> > >
> > > On Thu, Dec 19, 2024 at 2:42 PM Eric Dumazet <edumazet@google.com> wrote:
> > > >
> > > > On Thu, Dec 19, 2024 at 2:27 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> > > > >
> > > > > Corrected the netlink message size calculation for multicast group
> > > > > join/leave notifications. The previous calculation did not account for
> > > > > the inclusion of both IPv4/IPv6 addresses and ifa_cacheinfo in the
> > > > > payload. This fix ensures that the allocated message size is
> > > > > sufficient to hold all necessary information.
> > > > >
> > > > > Fixes: 2c2b61d2138f ("netlink: add IGMP/MLD join/leave notifications")
> > > > > Cc: Maciej Żenczykowski <maze@google.com>
> > > > > Cc: Lorenzo Colitti <lorenzo@google.com>
> > > > > Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
> > > > > ---
> > > > >  net/ipv4/igmp.c  | 4 +++-
> > > > >  net/ipv6/mcast.c | 4 +++-
> > > > >  2 files changed, 6 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
> > > > > index 8a370ef37d3f..4e2f1497f320 100644
> > > > > --- a/net/ipv4/igmp.c
> > > > > +++ b/net/ipv4/igmp.c
> > > > > @@ -1473,7 +1473,9 @@ static void inet_ifmcaddr_notify(struct net_device *dev,
> > > > >         int err = -ENOMEM;
> > > > >
> > > > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > > > -                       nla_total_size(sizeof(__be32)), GFP_ATOMIC);
> > > > > +                       nla_total_size(sizeof(__be32)) +
> > > > > +                       nla_total_size(sizeof(struct ifa_cacheinfo)),
> > > > > +                       GFP_ATOMIC);
> > > > >         if (!skb)
> > > > >                 goto error;
> > > > >
> > > > > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> > > > > index 587831c148de..b7430f15d1fc 100644
> > > > > --- a/net/ipv6/mcast.c
> > > > > +++ b/net/ipv6/mcast.c
> > > > > @@ -920,7 +920,9 @@ static void inet6_ifmcaddr_notify(struct net_device *dev,
> > > > >         int err = -ENOMEM;
> > > > >
> > > > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > > > -                       nla_total_size(16), GFP_ATOMIC);
> > > > > +                       nla_total_size(16) +
> > > >
> > > > While we are at it , can you use nla_total_size(sizeof(struct in6_addr))
> > > >
> > > > inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> > > > please remove it.
> > > > Squash the following in v2, thanks !
> > > >
> > > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> > > > index 2e2684886953d55140cd3d4a1e024b5218331a49..4da409bc45777f60fd37bdee541c61165a51d22c
> > > > 100644
> > > > --- a/net/ipv6/addrconf.c
> > > > +++ b/net/ipv6/addrconf.c
> > > > @@ -5239,7 +5239,6 @@ int inet6_fill_ifmcaddr(struct sk_buff *skb,
> > > >         nlmsg_end(skb, nlh);
> > > >         return 0;
> > > >  }
> > > > -EXPORT_SYMBOL(inet6_fill_ifmcaddr);
> > > >
> > > >  static int inet6_fill_ifacaddr(struct sk_buff *skb,
> > > >                                const struct ifacaddr6 *ifaca,
> > >
> > > Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.
> > >
> > > All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
> > > thus can sleep under memory pressure.
> > >
> > > Same remark for inet_ifmcaddr_notify()
Eric Dumazet Dec. 19, 2024, 3:50 p.m. UTC | #6
On Thu, Dec 19, 2024 at 4:28 PM Yuyang Huang <yuyanghuang@google.com> wrote:
>
> >Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.
>
> >All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
> >thus can sleep under memory pressure.
>
> I might not have enough background knowledge here, but why does
> holding RTNL imply that the callers are in process context?

RTNL is a mutex. Acquiring a mutex might sleep.

By looking at the code flow, you can see we do not hold a spinlock, or
block interrupts at this point,
or are in rcu_read_lock() section.

>
> Link: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/tree/net/ipv6/addrconf.c#n2241
>
> In addrconf.c, the logic joins the solicited-node multicast group and
> calls into mcast.c logic, which eventually triggers the notification.
> I guess this code path is not in process context when the kernel does
> SLAAC?

All these paths must be from process context.

Note that debug kernels have CONFIG_DEBUG_ATOMIC_SLEEP=y and would complain.



>
> Thanks,
> Yuyang
>
> On Thu, Dec 19, 2024 at 11:31 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> >
> > Hi Eric
> >
> > Thanks for the prompt review feedback. I will adjust all the comments
> > in the v2 patch.
> >
> > >inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> > please remove it.
> >
> > I  made the same mistake in Link:
> > https://lore.kernel.org/netdev/20241218090057.76899-1-yuyanghuang@google.com/T/
> >
> > I will fix that patch as well.
> >
> > Thanks,
> > Yuyang
> >
> > Thanks,
> > Yuyang
> >
> >
> > On Thu, Dec 19, 2024 at 10:47 PM Eric Dumazet <edumazet@google.com> wrote:
> > >
> > > On Thu, Dec 19, 2024 at 2:42 PM Eric Dumazet <edumazet@google.com> wrote:
> > > >
> > > > On Thu, Dec 19, 2024 at 2:27 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> > > > >
> > > > > Corrected the netlink message size calculation for multicast group
> > > > > join/leave notifications. The previous calculation did not account for
> > > > > the inclusion of both IPv4/IPv6 addresses and ifa_cacheinfo in the
> > > > > payload. This fix ensures that the allocated message size is
> > > > > sufficient to hold all necessary information.
> > > > >
> > > > > Fixes: 2c2b61d2138f ("netlink: add IGMP/MLD join/leave notifications")
> > > > > Cc: Maciej Żenczykowski <maze@google.com>
> > > > > Cc: Lorenzo Colitti <lorenzo@google.com>
> > > > > Signed-off-by: Yuyang Huang <yuyanghuang@google.com>
> > > > > ---
> > > > >  net/ipv4/igmp.c  | 4 +++-
> > > > >  net/ipv6/mcast.c | 4 +++-
> > > > >  2 files changed, 6 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
> > > > > index 8a370ef37d3f..4e2f1497f320 100644
> > > > > --- a/net/ipv4/igmp.c
> > > > > +++ b/net/ipv4/igmp.c
> > > > > @@ -1473,7 +1473,9 @@ static void inet_ifmcaddr_notify(struct net_device *dev,
> > > > >         int err = -ENOMEM;
> > > > >
> > > > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > > > -                       nla_total_size(sizeof(__be32)), GFP_ATOMIC);
> > > > > +                       nla_total_size(sizeof(__be32)) +
> > > > > +                       nla_total_size(sizeof(struct ifa_cacheinfo)),
> > > > > +                       GFP_ATOMIC);
> > > > >         if (!skb)
> > > > >                 goto error;
> > > > >
> > > > > diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
> > > > > index 587831c148de..b7430f15d1fc 100644
> > > > > --- a/net/ipv6/mcast.c
> > > > > +++ b/net/ipv6/mcast.c
> > > > > @@ -920,7 +920,9 @@ static void inet6_ifmcaddr_notify(struct net_device *dev,
> > > > >         int err = -ENOMEM;
> > > > >
> > > > >         skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
> > > > > -                       nla_total_size(16), GFP_ATOMIC);
> > > > > +                       nla_total_size(16) +
> > > >
> > > > While we are at it , can you use nla_total_size(sizeof(struct in6_addr))
> > > >
> > > > inet6_fill_ifmcaddr() got  an EXPORT_SYMBOL() for no good reason,
> > > > please remove it.
> > > > Squash the following in v2, thanks !
> > > >
> > > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> > > > index 2e2684886953d55140cd3d4a1e024b5218331a49..4da409bc45777f60fd37bdee541c61165a51d22c
> > > > 100644
> > > > --- a/net/ipv6/addrconf.c
> > > > +++ b/net/ipv6/addrconf.c
> > > > @@ -5239,7 +5239,6 @@ int inet6_fill_ifmcaddr(struct sk_buff *skb,
> > > >         nlmsg_end(skb, nlh);
> > > >         return 0;
> > > >  }
> > > > -EXPORT_SYMBOL(inet6_fill_ifmcaddr);
> > > >
> > > >  static int inet6_fill_ifacaddr(struct sk_buff *skb,
> > > >                                const struct ifacaddr6 *ifaca,
> > >
> > > Also GFP_ATOMIC should probably be replaced by GFP_KERNEL.
> > >
> > > All inet6_ifmcaddr_notify() callers are in process context, hold RTNL,
> > > thus can sleep under memory pressure.
> > >
> > > Same remark for inet_ifmcaddr_notify()
Eric Dumazet Dec. 19, 2024, 3:53 p.m. UTC | #7
On Thu, Dec 19, 2024 at 4:35 PM Yuyang Huang <yuyanghuang@google.com> wrote:
>
> >Same remark for inet_ifmcaddr_notify()
>
> Moreover, for both IPv4 and IPv6, when a device is up, the kernel
> joins the all-hosts multicast addresses (224.0.0.1/ff02::1). I guess
> this logic also does not run in process context?
>

Hopefully all these paths are stressed in kselftest.

A wrong gfp would trigger issues when you run the selftests before
submission, or in netdev CI.
Yuyang Huang Dec. 19, 2024, 4:13 p.m. UTC | #8
Thank you very much for the detailed explanation.

I will change GFP_ATOMIC to GFP_KERNEL in the v2 patch.

Thanks,
Yuyang

On Fri, Dec 20, 2024 at 12:53 AM Eric Dumazet <edumazet@google.com> wrote:
>
> On Thu, Dec 19, 2024 at 4:35 PM Yuyang Huang <yuyanghuang@google.com> wrote:
> >
> > >Same remark for inet_ifmcaddr_notify()
> >
> > Moreover, for both IPv4 and IPv6, when a device is up, the kernel
> > joins the all-hosts multicast addresses (224.0.0.1/ff02::1). I guess
> > this logic also does not run in process context?
> >
>
> Hopefully all these paths are stressed in kselftest.
>
> A wrong gfp would trigger issues when you run the selftests before
> submission, or in netdev CI.
diff mbox series

Patch

diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index 8a370ef37d3f..4e2f1497f320 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -1473,7 +1473,9 @@  static void inet_ifmcaddr_notify(struct net_device *dev,
 	int err = -ENOMEM;
 
 	skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
-			nla_total_size(sizeof(__be32)), GFP_ATOMIC);
+			nla_total_size(sizeof(__be32)) +
+			nla_total_size(sizeof(struct ifa_cacheinfo)),
+			GFP_ATOMIC);
 	if (!skb)
 		goto error;
 
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 587831c148de..b7430f15d1fc 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -920,7 +920,9 @@  static void inet6_ifmcaddr_notify(struct net_device *dev,
 	int err = -ENOMEM;
 
 	skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
-			nla_total_size(16), GFP_ATOMIC);
+			nla_total_size(16) +
+			nla_total_size(sizeof(struct ifa_cacheinfo)),
+			GFP_ATOMIC);
 	if (!skb)
 		goto error;