From: Kees Cook <k...@kernel.org> Date: Mon, 16 Dec 2024 23:53:46 -0800 > On December 16, 2024 6:41:56 PM PST, Kuniyuki Iwashima <kun...@amazon.com> > wrote: > >From: Kees Cook <k...@kernel.org> > >Date: Mon, 16 Dec 2024 18:04:45 -0800 > >> Instead of a heap allocation use a stack allocated struct sockaddr, as > >> dev_set_mac_address_user() is the consumer (which uses a classic > >> struct sockaddr). > > > >I remember Eric's feedback was to keep using heap instead of stack > >because rtnl_newlink() path already uses too much on stack. > > See below... > > > > > > >> Cap the copy to the minimum address size between > >> the incoming address and the traditional sa_data field itself. > >> > >> Putting "sa" on the stack means it will get a reused stack slot since > >> it is smaller than other existing single-scope stack variables (like > >> the vfinfo array). > > That's why I included the rationale above. (I.e. stack usage does not grow > with this patch.)
Ah okay, but I think we can't cap the address size to 14 bytes. MAX_ADDR_LEN is 32. Also, dev_set_mac_address_user() still uses dev->addr_len. > > -Kees > > >> > >> Signed-off-by: Kees Cook <k...@kernel.org> > >> --- > >> Cc: Eric Dumazet <eduma...@google.com> > >> Cc: "David S. Miller" <da...@davemloft.net> > >> Cc: Jakub Kicinski <k...@kernel.org> > >> Cc: Paolo Abeni <pab...@redhat.com> > >> Cc: Ido Schimmel <ido...@nvidia.com> > >> Cc: Petr Machata <pe...@nvidia.com> > >> Cc: net...@vger.kernel.org > >> --- > >> net/core/rtnetlink.c | 22 +++++++--------------- > >> 1 file changed, 7 insertions(+), 15 deletions(-) > >> > >> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c > >> index ab5f201bf0ab..6da0edc0870d 100644 > >> --- a/net/core/rtnetlink.c > >> +++ b/net/core/rtnetlink.c > >> @@ -3048,21 +3048,13 @@ static int do_setlink(const struct sk_buff *skb, > >> struct net_device *dev, > >> } > >> > >> if (tb[IFLA_ADDRESS]) { > >> - struct sockaddr *sa; > >> - int len; > >> - > >> - len = sizeof(sa_family_t) + max_t(size_t, dev->addr_len, > >> - sizeof(*sa)); > >> - sa = kmalloc(len, GFP_KERNEL); > >> - if (!sa) { > >> - err = -ENOMEM; > >> - goto errout; > >> - } > >> - sa->sa_family = dev->type; > >> - memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), > >> - dev->addr_len); > >> - err = dev_set_mac_address_user(dev, sa, extack); > >> - kfree(sa); > >> + struct sockaddr sa = { }; > >> + > >> + /* dev_set_mac_address_user() uses a true struct sockaddr. */ > >> + sa.sa_family = dev->type; > >> + memcpy(sa.sa_data, nla_data(tb[IFLA_ADDRESS]), > >> + min(dev->addr_len, sizeof(sa.sa_data_min))); > >> + err = dev_set_mac_address_user(dev, &sa, extack); > >> if (err) > >> goto errout; > >> status |= DO_SETLINK_MODIFIED; > >> -- > >> 2.34.1 > > > > -- > Kees Cook