diff options
author | Nikolay Aleksandrov <nikolay@redhat.com> | 2013-11-13 11:07:46 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-14 16:28:52 -0500 |
commit | b869ccfab1e324507fa3596e3e1308444fb68227 (patch) | |
tree | eb35bfa07b83170abf65fbd88841d013b573e255 /drivers/net/bonding | |
parent | 98e09386c0ef4dfd48af7ba60ff908f0d525cdee (diff) |
bonding: fix two race conditions in bond_store_updelay/downdelay
This patch fixes two race conditions between bond_store_updelay/downdelay
and bond_store_miimon which could lead to division by zero as miimon can
be set to 0 while either updelay/downdelay are being set and thus miss the
zero check in the beginning, the zero div happens because updelay/downdelay
are stored as new_value / bond->params.miimon. Use rtnl to synchronize with
miimon setting.
CC: Jay Vosburgh <fubar@us.ibm.com>
CC: Andy Gospodarek <andy@greyhouse.net>
CC: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: Nikolay Aleksandrov <nikolay@redhat.com>
Acked-by: Veaceslav Falico <vfalico@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/bonding')
-rw-r--r-- | drivers/net/bonding/bond_sysfs.c | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 6245d92b7a0c..9f32e2304004 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -702,6 +702,8 @@ static ssize_t bonding_store_downdelay(struct device *d, | |||
702 | int new_value, ret = count; | 702 | int new_value, ret = count; |
703 | struct bonding *bond = to_bond(d); | 703 | struct bonding *bond = to_bond(d); |
704 | 704 | ||
705 | if (!rtnl_trylock()) | ||
706 | return restart_syscall(); | ||
705 | if (!(bond->params.miimon)) { | 707 | if (!(bond->params.miimon)) { |
706 | pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", | 708 | pr_err("%s: Unable to set down delay as MII monitoring is disabled\n", |
707 | bond->dev->name); | 709 | bond->dev->name); |
@@ -735,6 +737,7 @@ static ssize_t bonding_store_downdelay(struct device *d, | |||
735 | } | 737 | } |
736 | 738 | ||
737 | out: | 739 | out: |
740 | rtnl_unlock(); | ||
738 | return ret; | 741 | return ret; |
739 | } | 742 | } |
740 | static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR, | 743 | static DEVICE_ATTR(downdelay, S_IRUGO | S_IWUSR, |
@@ -757,6 +760,8 @@ static ssize_t bonding_store_updelay(struct device *d, | |||
757 | int new_value, ret = count; | 760 | int new_value, ret = count; |
758 | struct bonding *bond = to_bond(d); | 761 | struct bonding *bond = to_bond(d); |
759 | 762 | ||
763 | if (!rtnl_trylock()) | ||
764 | return restart_syscall(); | ||
760 | if (!(bond->params.miimon)) { | 765 | if (!(bond->params.miimon)) { |
761 | pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", | 766 | pr_err("%s: Unable to set up delay as MII monitoring is disabled\n", |
762 | bond->dev->name); | 767 | bond->dev->name); |
@@ -790,6 +795,7 @@ static ssize_t bonding_store_updelay(struct device *d, | |||
790 | } | 795 | } |
791 | 796 | ||
792 | out: | 797 | out: |
798 | rtnl_unlock(); | ||
793 | return ret; | 799 | return ret; |
794 | } | 800 | } |
795 | static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR, | 801 | static DEVICE_ATTR(updelay, S_IRUGO | S_IWUSR, |