Re: net: parsing IFLA_INET_CONF broken since 7.1 if NLA_F_NESTED not set
flat view
From: Ido Schimmel <idosch@nvidia.com>
Date: 2026-09-14 15:42:26
Subsystem:
networking [general], networking [ipv4/ipv6], the rest · Maintainers:
"David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, David Ahern, Ido Schimmel, Linus Torvalds
On Mon, Sep 14, 2026 at 06:27:21PM +0300, Ido Schimmel wrote:
quoted hunk ↗ jump to hunk
On Mon, Sep 14, 2026 at 03:21:59PM +0100, Quentin Armitage wrote:quoted
Commit fa8fca88714c - "ipv4: validate IPV4_DEVCONF attributes properly" changed inet_validate_link_af() to call nla_parse_nested() rather than nla_for_each_nested() for IFLA_INET_CONF. A side effect of this change is that the code now checks that NLA_F_NESTED is set for IFLA_INET_CONF, and rejects the message if it is not, whereas previously there was no check for NLA_F_NESTED being set. The consequence of this is that code which worked prior to Linux 7.1, albeit erroneously not setting NLA_F_NESTED now fails. In order to maintain backward compatibility, rather than calling nla_parse_nested(), nla_parse_nested_deprecated() should be called, as it is earlier in the function.I don't think nla_parse_nested_deprecated() is safe. It will allow attributes exceeding the maximum type or with type 0, which can then crash in inet_set_link_af(). Can you try nla_parse_deprecated_strict() instead?diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index a90be57c63be..4e0e153f504f 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c@@ -2117,10 +2117,10 @@ static int inet_validate_link_af(const struct net_device *dev, return err; if (tb[IFLA_INET_CONF]) { - err = nla_parse_nested(nested_tb, IPV4_DEVCONF_MAX, - tb[IFLA_INET_CONF], inet_devconf_policy, - extack); - + err = nla_parse_deprecated_strict(nested_tb, IPV4_DEVCONF_MAX, + nla_data(tb[IFLA_INET_CONF]), + nla_len(tb[IFLA_INET_CONF]), + inet_devconf_policy, extack); if (err < 0) return err; }
Actually, nla_parse() would be closer to what is currently in the tree and should still fix the breakage:
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index a90be57c63be..1f747826542a 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c@@ -2117,10 +2117,10 @@ static int inet_validate_link_af(const struct net_device *dev, return err; if (tb[IFLA_INET_CONF]) { - err = nla_parse_nested(nested_tb, IPV4_DEVCONF_MAX, - tb[IFLA_INET_CONF], inet_devconf_policy, - extack); - + err = nla_parse(nested_tb, IPV4_DEVCONF_MAX, + nla_data(tb[IFLA_INET_CONF]), + nla_len(tb[IFLA_INET_CONF]), + inet_devconf_policy, extack); if (err < 0) return err; }