Commit c5da4b68 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge branch 'bonding-fix-null-deref-in-bond_rr_gen_slave_id'

Jonathan Toppins says:

====================
bonding: fix NULL deref in bond_rr_gen_slave_id

Fix a NULL dereference of the struct bonding.rr_tx_counter member because
if a bond is initially created with an initial mode != zero (Round Robin)
the memory required for the counter is never created and when the mode is
changed there is never any attempt to verify the memory is allocated upon
switching modes.
====================

Link: https://lore.kernel.org/r/cover.1663694476.git.jtoppins@redhat.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 2002fbac 2ffd5732
...@@ -4182,6 +4182,12 @@ static int bond_open(struct net_device *bond_dev) ...@@ -4182,6 +4182,12 @@ static int bond_open(struct net_device *bond_dev)
struct list_head *iter; struct list_head *iter;
struct slave *slave; struct slave *slave;
if (BOND_MODE(bond) == BOND_MODE_ROUNDROBIN && !bond->rr_tx_counter) {
bond->rr_tx_counter = alloc_percpu(u32);
if (!bond->rr_tx_counter)
return -ENOMEM;
}
/* reset slave->backup and slave->inactive */ /* reset slave->backup and slave->inactive */
if (bond_has_slaves(bond)) { if (bond_has_slaves(bond)) {
bond_for_each_slave(bond, slave, iter) { bond_for_each_slave(bond, slave, iter) {
...@@ -6243,15 +6249,6 @@ static int bond_init(struct net_device *bond_dev) ...@@ -6243,15 +6249,6 @@ static int bond_init(struct net_device *bond_dev)
if (!bond->wq) if (!bond->wq)
return -ENOMEM; return -ENOMEM;
if (BOND_MODE(bond) == BOND_MODE_ROUNDROBIN) {
bond->rr_tx_counter = alloc_percpu(u32);
if (!bond->rr_tx_counter) {
destroy_workqueue(bond->wq);
bond->wq = NULL;
return -ENOMEM;
}
}
spin_lock_init(&bond->stats_lock); spin_lock_init(&bond->stats_lock);
netdev_lockdep_set_classes(bond_dev); netdev_lockdep_set_classes(bond_dev);
......
...@@ -2,7 +2,8 @@ ...@@ -2,7 +2,8 @@
# Makefile for net selftests # Makefile for net selftests
TEST_PROGS := bond-break-lacpdu-tx.sh \ TEST_PROGS := bond-break-lacpdu-tx.sh \
dev_addr_lists.sh dev_addr_lists.sh \
bond-arp-interval-causes-panic.sh
TEST_FILES := lag_lib.sh TEST_FILES := lag_lib.sh
......
#!/bin/sh
# SPDX-License-Identifier: GPL-2.0
#
# cause kernel oops in bond_rr_gen_slave_id
DEBUG=${DEBUG:-0}
set -e
test ${DEBUG} -ne 0 && set -x
finish()
{
ip netns delete server || true
ip netns delete client || true
ip link del link1_1 || true
}
trap finish EXIT
client_ip4=192.168.1.198
server_ip4=192.168.1.254
# setup kernel so it reboots after causing the panic
echo 180 >/proc/sys/kernel/panic
# build namespaces
ip link add dev link1_1 type veth peer name link1_2
ip netns add "server"
ip link set dev link1_2 netns server up name eth0
ip netns exec server ip addr add ${server_ip4}/24 dev eth0
ip netns add "client"
ip link set dev link1_1 netns client down name eth0
ip netns exec client ip link add dev bond0 down type bond mode 1 \
miimon 100 all_slaves_active 1
ip netns exec client ip link set dev eth0 down master bond0
ip netns exec client ip link set dev bond0 up
ip netns exec client ip addr add ${client_ip4}/24 dev bond0
ip netns exec client ping -c 5 $server_ip4 >/dev/null
ip netns exec client ip link set dev eth0 down nomaster
ip netns exec client ip link set dev bond0 down
ip netns exec client ip link set dev bond0 type bond mode 0 \
arp_interval 1000 arp_ip_target "+${server_ip4}"
ip netns exec client ip link set dev eth0 down master bond0
ip netns exec client ip link set dev bond0 up
ip netns exec client ping -c 5 $server_ip4 >/dev/null
exit 0
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment