History

net: nexthop: Add flag to assert that NHGRP reserved fields are zero

There are many unpatched kernel versions out there that do not initialize the reserved fields of struct nexthop_grp. The issue with that is that if those fields were to be used for some end (i.e. stop being reserved), old kernels would still keep sending random data through the field, and a new userspace could not rely on the value. In this patch, use the existing NHA_OP_FLAGS, which is currently inbound only, to carry flags back to the userspace. Add a flag to indicate that the reserved fields in struct nexthop_grp are zeroed before dumping. This is reliant on the actual fix from commit 6d745cd0e972 ("net: nexthop: Initialize all fields in dumped nexthops").

Petr Machata committed 2 years ago

Commit 75bab451 parent 246ef402 files · +12 −3Browse files

Unified · Split

2 files
  1. include/uapi/linux/nexthop.h +3 −0
  2. net/ipv4/nexthop.c +9 −3
include/uapi/linux/nexthop.h+3−0
@@ -33,6 +33,9 @@ enum { · 32 unmodified lines
3333 #define NHA_OP_FLAG_DUMP_STATS BIT(0)
3434 #define NHA_OP_FLAG_DUMP_HW_STATS BIT(1)
3535
36+/* Response OP_FLAGS. */
37+#define NHA_OP_FLAG_RESP_GRP_RESVD_0 BIT(31) /* Dump clears resvd fields. */
38+
3639 enum {
3740 NHA_UNSPEC,
3841 NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */
net/ipv4/nexthop.c+9−3
@@ -865,7 +865,7 @@ out: · 864 unmodified lines
865865 }
866866
867867 static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh,
868− u32 op_flags)
868+ u32 op_flags, u32 *resp_op_flags)
869869 {
870870 struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
871871 struct nexthop_grp *p;
@@ -874,6 +874,8 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh, · 2 unmodified lines
874874 u16 group_type = 0;
875875 int i;
876876
877+ *resp_op_flags |= NHA_OP_FLAG_RESP_GRP_RESVD_0;
878+
877879 if (nhg->hash_threshold)
878880 group_type = NEXTHOP_GRP_TYPE_MPATH;
879881 else if (nhg->resilient)
@@ -934,10 +936,12 @@ static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh, · 54 unmodified lines
934936
935937 if (nh->is_group) {
936938 struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
939+ u32 resp_op_flags = 0;
937940
938941 if (nhg->fdb_nh && nla_put_flag(skb, NHA_FDB))
939942 goto nla_put_failure;
940− if (nla_put_nh_group(skb, nh, op_flags))
943+ if (nla_put_nh_group(skb, nh, op_flags, &resp_op_flags) ||
944+ nla_put_u32(skb, NHA_OP_FLAGS, resp_op_flags))
941945 goto nla_put_failure;
942946 goto out;
943947 }
@@ -1050,7 +1054,9 @@ static size_t nh_nlmsg_size(struct nexthop *nh) · 106 unmodified lines
10501054 sz += nla_total_size(4); /* NHA_ID */
10511055
10521056 if (nh->is_group)
1053− sz += nh_nlmsg_size_grp(nh);
1057+ sz += nh_nlmsg_size_grp(nh) +
1058+ nla_total_size(4) + /* NHA_OP_FLAGS */
1059+ 0;
10541060 else
10551061 sz += nh_nlmsg_size_single(nh);
10561062