FAILED: patch "[PATCH] ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops" failed to apply to 5.10-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 5.10-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.10.y
git checkout FETCH_HEAD
git cherry-pick -x 4ff9548d84945d2cbf9e4c207288063a200ea397
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026081713-siesta-mute-edca@gregkh' --subject-prefix 'PATCH 5.10.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 4ff9548d84945d2cbf9e4c207288063a200ea397 Mon Sep 17 00:00:00 2001
From: Zihan Xi <[email protected]>
Date: Thu, 30 Jul 2026 12:59:26 +0000
Subject: [PATCH] ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops
fib_nlmsg_size() still estimates nexthop space as if every gateway is encoded as an IPv4 RTA_GATEWAY attribute. IPv4 routes can also carry an IPv6 gateway, which fib_nexthop_info() dumps as RTA_VIA.
As a result, route notifications can allocate an skb that is too small. fib_dump_info() then fails with -EMSGSIZE and rtmsg_fib() hits the WARN_ON() that marks such failures as a fib_nlmsg_size() bug. With panic_on_warn set, this becomes a kernel panic.
Mirror the actual nexthop dump layout in fib_nlmsg_size(): account for IPv6 nexthop gateways dumped as RTA_VIA, for the no-header rtnexthop layout used inside RTA_MULTIPATH, and for RTA_FLOW only when it is actually present.
net/ipv4/fib_semantics.c +49 -18
@@ -490,6 +490,34 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)return -1 ; } +static size_t fib_nexthop_nlmsg_size (const struct fib_nh_common *nhc, +bool skip_oif) +{ +size_t nhsize =0 ; + +switch (nhc->nhc_gw_family) { +case AF_INET : + nhsize +=nla_total_size (4 );/* RTA_GATEWAY */ +break ; +case AF_INET6 : + nhsize +=nla_total_size (sizeof (struct rtvia ) + +sizeof (struct in6_addr )); +break ; + } + +if (!skip_oif && nhc->nhc_dev) + nhsize +=nla_total_size (4 );/* RTA_OIF */ + +if (nhc->nhc_lwtstate) { +/* RTA_ENCAP */ + nhsize +=lwtunnel_get_encap_size (nhc->nhc_lwtstate); +/* RTA_ENCAP_TYPE */ + nhsize +=nla_total_size (2 ); + } + +return nhsize; +} +size_t fib_nlmsg_size (struct fib_info *fi) {size_t payload =NLMSG_ALIGN (sizeof (struct rtmsg ))
@@ -507,32 +535,35 @@ size_t fib_nlmsg_size(struct fib_info *fi) payload +=nla_total_size (4 );/* RTA_NH_ID */ if (nhs) { -size_t nh_encapsize =0 ; -/* Also handles the special case nhs == 1 */ - -/* each nexthop is packed in an attribute */ -size_t nhsize =nla_total_size (sizeof (struct rtnexthop )); +size_t mpsize =0 ;unsigned int i; -/* may contain flow and gateway attribute */ - nhsize +=2 *nla_total_size (4 ); - -/* grab encap info */ for (i =0 ; i <fib_info_num_path (fi); i++) {struct fib_nh_common *nhc =fib_info_nhc (fi, i); +size_t nhsize; -if (nhc->nhc_lwtstate) { -/* RTA_ENCAP_TYPE */ - nh_encapsize +=lwtunnel_get_encap_size ( - nhc->nhc_lwtstate); -/* RTA_ENCAP */ - nh_encapsize +=nla_total_size (2 ); + nhsize =fib_nexthop_nlmsg_size (nhc, nhs !=1 ); + +if (nhs !=1 ) + nhsize +=NLA_ALIGN (sizeof (struct rtnexthop )); + +#ifdef CONFIG_IP_ROUTE_CLASSID +if (nhc->nhc_family ==AF_INET ) { +struct fib_nh *nh; + + nh = container_of(nhc, struct fib_nh, nh_common); +if (nh->nh_tclassid) + nhsize +=nla_total_size (4 ); } +#endif +if (nhs ==1 ) + payload += nhsize; +else + mpsize += nhsize; } -/* all nexthops are packed in a nested attribute */ - payload +=nla_total_size ((nhs * nhsize) + nh_encapsize); - +if (nhs !=1 ) + payload +=nla_total_size (mpsize); }return payload;
Sasha Levin
maintainerPATCH 1/2 net: ipv4: Publish fib_nlmsg_size()
From: Amit Cohen <[email protected]>
[ Upstream commit 1e7bdec6bbc7816cdc6a093374f4bf4e732c3d44 ]
Publish fib_nlmsg_size() to allow it to be used later on from fib_alias_hw_flags_set().
Remove the inline keyword since it shouldn't be used inside C files.
Stable-dep-of: 4ff9548d8494 ("ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops")
--- net/ipv4/fib_lookup.h | 1 + net/ipv4/fib_semantics.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
net/ipv4/fib_lookup.h +1 -0
@@ -44,6 +44,7 @@ int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, struct fib_rt_info *fri, unsigned int flags);void rtmsg_fib (int event,__be32 key,struct fib_alias *fa,int dst_len,u32 tb_id,const struct nl_info *info,unsigned int nlm_flags); +size_t fib_nlmsg_size (struct fib_info *fi);static inline void fib_result_assign (struct fib_result *res,struct fib_info *fi)
net/ipv4/fib_semantics.c +1 -1
@@ -460,7 +460,7 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)return -1 ; } -static inline size_t fib_nlmsg_size (struct fib_info *fi) +size_t fib_nlmsg_size (struct fib_info *fi) {size_t payload =NLMSG_ALIGN (sizeof (struct rtmsg )) +nla_total_size (4 )/* RTA_TABLE */
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 ipv4: Fix fib_nlmsg_size() for RTA_VIA nexthops
From: Zihan Xi <[email protected]>
[ Upstream commit 4ff9548d84945d2cbf9e4c207288063a200ea397 ]
fib_nlmsg_size() still estimates nexthop space as if every gateway is encoded as an IPv4 RTA_GATEWAY attribute. IPv4 routes can also carry an IPv6 gateway, which fib_nexthop_info() dumps as RTA_VIA.
As a result, route notifications can allocate an skb that is too small. fib_dump_info() then fails with -EMSGSIZE and rtmsg_fib() hits the WARN_ON() that marks such failures as a fib_nlmsg_size() bug. With panic_on_warn set, this becomes a kernel panic.
Mirror the actual nexthop dump layout in fib_nlmsg_size(): account for IPv6 nexthop gateways dumped as RTA_VIA, for the no-header rtnexthop layout used inside RTA_MULTIPATH, and for RTA_FLOW only when it is actually present.
--- net/ipv4/fib_semantics.c | 67 +++++++++++++++++++++++++++++----------- 1 file changed, 49 insertions(+), 18 deletions(-)
net/ipv4/fib_semantics.c +49 -18
@@ -460,6 +460,34 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev)return -1 ; } +static size_t fib_nexthop_nlmsg_size (const struct fib_nh_common *nhc, +bool skip_oif) +{ +size_t nhsize =0 ; + +switch (nhc->nhc_gw_family) { +case AF_INET : + nhsize +=nla_total_size (4 );/* RTA_GATEWAY */ +break ; +case AF_INET6 : + nhsize +=nla_total_size (sizeof (struct rtvia ) + +sizeof (struct in6_addr )); +break ; + } + +if (!skip_oif && nhc->nhc_dev) + nhsize +=nla_total_size (4 );/* RTA_OIF */ + +if (nhc->nhc_lwtstate) { +/* RTA_ENCAP */ + nhsize +=lwtunnel_get_encap_size (nhc->nhc_lwtstate); +/* RTA_ENCAP_TYPE */ + nhsize +=nla_total_size (2 ); + } + +return nhsize; +} +size_t fib_nlmsg_size (struct fib_info *fi) {size_t payload =NLMSG_ALIGN (sizeof (struct rtmsg ))
@@ -477,32 +505,35 @@ size_t fib_nlmsg_size(struct fib_info *fi) payload +=nla_total_size (4 );/* RTA_NH_ID */ if (nhs) { -size_t nh_encapsize =0 ; -/* Also handles the special case nhs == 1 */ - -/* each nexthop is packed in an attribute */ -size_t nhsize =nla_total_size (sizeof (struct rtnexthop )); +size_t mpsize =0 ;unsigned int i; -/* may contain flow and gateway attribute */ - nhsize +=2 *nla_total_size (4 ); - -/* grab encap info */ for (i =0 ; i <fib_info_num_path (fi); i++) {struct fib_nh_common *nhc =fib_info_nhc (fi, i); +size_t nhsize; + + nhsize =fib_nexthop_nlmsg_size (nhc, nhs !=1 ); -if (nhc->nhc_lwtstate) { -/* RTA_ENCAP_TYPE */ - nh_encapsize +=lwtunnel_get_encap_size ( - nhc->nhc_lwtstate); -/* RTA_ENCAP */ - nh_encapsize +=nla_total_size (2 ); +if (nhs !=1 ) + nhsize +=NLA_ALIGN (sizeof (struct rtnexthop )); + +#ifdef CONFIG_IP_ROUTE_CLASSID +if (nhc->nhc_family ==AF_INET ) { +struct fib_nh *nh; + + nh = container_of(nhc, struct fib_nh, nh_common); +if (nh->nh_tclassid) + nhsize +=nla_total_size (4 ); } +#endif +if (nhs ==1 ) + payload += nhsize; +else + mpsize += nhsize; } -/* all nexthops are packed in a nested attribute */ - payload +=nla_total_size ((nhs * nhsize) + nh_encapsize); - +if (nhs !=1 ) + payload +=nla_total_size (mpsize); }return payload;
Signature · 1 line
2.53.0