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
33#define NHA_OP_FLAG_DUMP_STATS BIT(0)33#define NHA_OP_FLAG_DUMP_STATS BIT(0)
34#define NHA_OP_FLAG_DUMP_HW_STATS BIT(1)34#define NHA_OP_FLAG_DUMP_HW_STATS BIT(1)
35 35
36/* Response OP_FLAGS. */
37#define NHA_OP_FLAG_RESP_GRP_RESVD_0 BIT(31) /* Dump clears resvd fields. */
38
36enum {39enum {
37 NHA_UNSPEC,40 NHA_UNSPEC,
38 NHA_ID, /* u32; id for nexthop. id == 0 means auto-assign */41 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
865}865}
866 866
867static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh,867static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh,
868 u32 op_flags)868 u32 op_flags, u32 *resp_op_flags)
869{869{
870 struct nh_group *nhg = rtnl_dereference(nh->nh_grp);870 struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
871 struct nexthop_grp *p;871 struct nexthop_grp *p;
@@ -874,6 +874,8 @@ static int nla_put_nh_group(struct sk_buff *skb, struct nexthop *nh, · 2 unmodified lines
874 u16 group_type = 0;874 u16 group_type = 0;
875 int i;875 int i;
876 876
877 *resp_op_flags |= NHA_OP_FLAG_RESP_GRP_RESVD_0;
878
877 if (nhg->hash_threshold)879 if (nhg->hash_threshold)
878 group_type = NEXTHOP_GRP_TYPE_MPATH;880 group_type = NEXTHOP_GRP_TYPE_MPATH;
879 else if (nhg->resilient)881 else if (nhg->resilient)
@@ -934,10 +936,12 @@ static int nh_fill_node(struct sk_buff *skb, struct nexthop *nh, · 54 unmodified lines
934 936
935 if (nh->is_group) {937 if (nh->is_group) {
936 struct nh_group *nhg = rtnl_dereference(nh->nh_grp);938 struct nh_group *nhg = rtnl_dereference(nh->nh_grp);
939 u32 resp_op_flags = 0;
937 940
938 if (nhg->fdb_nh && nla_put_flag(skb, NHA_FDB))941 if (nhg->fdb_nh && nla_put_flag(skb, NHA_FDB))
939 goto nla_put_failure;942 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))
941 goto nla_put_failure;945 goto nla_put_failure;
942 goto out;946 goto out;
943 }947 }
@@ -1050,7 +1054,9 @@ static size_t nh_nlmsg_size(struct nexthop *nh) · 106 unmodified lines
1050 sz += nla_total_size(4); /* NHA_ID */1054 sz += nla_total_size(4); /* NHA_ID */
1051 1055
1052 if (nh->is_group)1056 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;
1054 else1060 else
1055 sz += nh_nlmsg_size_single(nh);1061 sz += nh_nlmsg_size_single(nh);
1056 1062