Message ID | 20230427033909.4109569-2-liuhangbin@gmail.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | bonding: fix send_peer_notif overflow | expand |
On Thu, Apr 27, 2023 at 11:39:06AM +0800, Hangbin Liu wrote: ... > diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c > index c2d080fc4fc4..09a501cdea0c 100644 > --- a/drivers/net/bonding/bond_netlink.c > +++ b/drivers/net/bonding/bond_netlink.c > @@ -244,6 +244,12 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[], > if (data[IFLA_BOND_PEER_NOTIF_DELAY]) { > int delay = nla_get_u32(data[IFLA_BOND_PEER_NOTIF_DELAY]); > > + if (delay > 300000) { > + NL_SET_ERR_MSG_ATTR(extack, data[IFLA_BOND_PEER_NOTIF_DELAY], > + "peer_notif_delay should be less than 300s"); > + return -EINVAL; > + } Hi Hangbin, can this limit be implemented using NLA_POLICY_MAX() in bond_policy ? > + > bond_opt_initval(&newval, delay); > err = __bond_opt_set(bond, BOND_OPT_PEER_NOTIF_DELAY, &newval, > data[IFLA_BOND_PEER_NOTIF_DELAY], extack); ...
On Fri, Apr 28, 2023 at 10:04:22PM +0200, Simon Horman wrote: > On Thu, Apr 27, 2023 at 11:39:06AM +0800, Hangbin Liu wrote: > > ... > > > diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c > > index c2d080fc4fc4..09a501cdea0c 100644 > > --- a/drivers/net/bonding/bond_netlink.c > > +++ b/drivers/net/bonding/bond_netlink.c > > @@ -244,6 +244,12 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[], > > if (data[IFLA_BOND_PEER_NOTIF_DELAY]) { > > int delay = nla_get_u32(data[IFLA_BOND_PEER_NOTIF_DELAY]); > > > > + if (delay > 300000) { > > + NL_SET_ERR_MSG_ATTR(extack, data[IFLA_BOND_PEER_NOTIF_DELAY], > > + "peer_notif_delay should be less than 300s"); > > + return -EINVAL; > > + } > > Hi Hangbin, > > can this limit be implemented using NLA_POLICY_MAX() in bond_policy ? Thanks for the comment, I will update the patch after backing from holiday next week. Hangbin
diff --git a/drivers/net/bonding/bond_netlink.c b/drivers/net/bonding/bond_netlink.c index c2d080fc4fc4..09a501cdea0c 100644 --- a/drivers/net/bonding/bond_netlink.c +++ b/drivers/net/bonding/bond_netlink.c @@ -244,6 +244,12 @@ static int bond_changelink(struct net_device *bond_dev, struct nlattr *tb[], if (data[IFLA_BOND_PEER_NOTIF_DELAY]) { int delay = nla_get_u32(data[IFLA_BOND_PEER_NOTIF_DELAY]); + if (delay > 300000) { + NL_SET_ERR_MSG_ATTR(extack, data[IFLA_BOND_PEER_NOTIF_DELAY], + "peer_notif_delay should be less than 300s"); + return -EINVAL; + } + bond_opt_initval(&newval, delay); err = __bond_opt_set(bond, BOND_OPT_PEER_NOTIF_DELAY, &newval, data[IFLA_BOND_PEER_NOTIF_DELAY], extack); diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c index f71d5517f829..5310cb488f11 100644 --- a/drivers/net/bonding/bond_options.c +++ b/drivers/net/bonding/bond_options.c @@ -169,6 +169,12 @@ static const struct bond_opt_value bond_num_peer_notif_tbl[] = { { NULL, -1, 0} }; +static const struct bond_opt_value bond_peer_notif_delay_tbl[] = { + { "off", 0, 0}, + { "maxval", 300000, BOND_VALFLAG_MAX}, + { NULL, -1, 0} +}; + static const struct bond_opt_value bond_primary_reselect_tbl[] = { { "always", BOND_PRI_RESELECT_ALWAYS, BOND_VALFLAG_DEFAULT}, { "better", BOND_PRI_RESELECT_BETTER, 0}, @@ -488,7 +494,7 @@ static const struct bond_option bond_opts[BOND_OPT_LAST] = { .id = BOND_OPT_PEER_NOTIF_DELAY, .name = "peer_notif_delay", .desc = "Delay between each peer notification on failover event, in milliseconds", - .values = bond_intmax_tbl, + .values = bond_peer_notif_delay_tbl, .set = bond_option_peer_notif_delay_set } }; diff --git a/include/net/bonding.h b/include/net/bonding.h index c3843239517d..2d034e07b796 100644 --- a/include/net/bonding.h +++ b/include/net/bonding.h @@ -233,7 +233,7 @@ struct bonding { */ spinlock_t mode_lock; spinlock_t stats_lock; - u8 send_peer_notif; + u32 send_peer_notif; u8 igmp_retrans; #ifdef CONFIG_PROC_FS struct proc_dir_entry *proc_entry;
Bonding send_peer_notif was defined as u8. Since commit 07a4ddec3ce9 ("bonding: add an option to specify a delay between peer notifications"). the bond->send_peer_notif will be num_peer_notif multiplied by peer_notif_delay, which is u8 * u32. This would cause the send_peer_notif overflow easily. e.g. ip link add bond0 type bond mode 1 miimon 100 num_grat_arp 30 peer_notify_delay 1000 To fix the overflow, let's set the send_peer_notif to u32 and limit peer_notif_delay to 300s. Fixes: 07a4ddec3ce9 ("bonding: add an option to specify a delay between peer notifications") Reported-by: Liang Li <liali@redhat.com> Signed-off-by: Hangbin Liu <liuhangbin@gmail.com> --- v2: define send_peer_notif as u32 and limit the peer_notif_delay to 300s --- drivers/net/bonding/bond_netlink.c | 6 ++++++ drivers/net/bonding/bond_options.c | 8 +++++++- include/net/bonding.h | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-)