lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 18 Aug 2022 18:49:02 +0300
From:   Vladimir Oltean <vladimir.oltean@....com>
To:     netdev@...r.kernel.org
Cc:     Andrew Lunn <andrew@...n.ch>,
        Vivien Didelot <vivien.didelot@...il.com>,
        Florian Fainelli <f.fainelli@...il.com>,
        Vladimir Oltean <olteanv@...il.com>,
        "David S. Miller" <davem@...emloft.net>,
        Eric Dumazet <edumazet@...gle.com>,
        Jakub Kicinski <kuba@...nel.org>,
        Paolo Abeni <pabeni@...hat.com>,
        "Rafael J. Wysocki" <rafael@...nel.org>,
        Kevin Hilman <khilman@...nel.org>,
        Ulf Hansson <ulf.hansson@...aro.org>,
        Len Brown <len.brown@...el.com>, Pavel Machek <pavel@....cz>,
        Greg Kroah-Hartman <gregkh@...uxfoundation.org>
Subject: [RFC PATCH net-next 01/10] notifier: allow robust variants to take a different void *v argument on rollback

More notifier call chain users would like to convert to the robust form
to simplify the rollback, but sometimes the events are of "SET" type,
and the void *v describes the object to set. In that case, the rollback
will also be a "SET" event, but the void *v has to describe the old
object. This pattern is not possible using the current
notifier_call_chain_robust() function.

Expand the prototypes of blocking_notifier_call_chain_robust() and
raw_notifier_call_chain_robust() by explicitly asking for the void *v to
use on rollback. Modify all callers to supply the same "void *v" as for
the normal call.

Signed-off-by: Vladimir Oltean <vladimir.oltean@....com>
---
 drivers/base/power/domain.c |  4 ++--
 include/linux/notifier.h    |  8 ++++++--
 kernel/cpu_pm.c             |  3 ++-
 kernel/module/main.c        |  4 +++-
 kernel/notifier.c           | 21 +++++++++++++--------
 kernel/power/main.c         |  3 ++-
 net/core/dev.c              |  2 +-
 7 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c
index 5a2e0232862e..0b85236249c7 100644
--- a/drivers/base/power/domain.c
+++ b/drivers/base/power/domain.c
@@ -504,7 +504,7 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
 	/* Notify consumers that we are about to power on. */
 	ret = raw_notifier_call_chain_robust(&genpd->power_notifiers,
 					     GENPD_NOTIFY_PRE_ON,
-					     GENPD_NOTIFY_OFF, NULL);
+					     GENPD_NOTIFY_OFF, NULL, NULL);
 	ret = notifier_to_errno(ret);
 	if (ret)
 		return ret;
@@ -554,7 +554,7 @@ static int _genpd_power_off(struct generic_pm_domain *genpd, bool timed)
 	/* Notify consumers that we are about to power off. */
 	ret = raw_notifier_call_chain_robust(&genpd->power_notifiers,
 					     GENPD_NOTIFY_PRE_OFF,
-					     GENPD_NOTIFY_ON, NULL);
+					     GENPD_NOTIFY_ON, NULL, NULL);
 	ret = notifier_to_errno(ret);
 	if (ret)
 		return ret;
diff --git a/include/linux/notifier.h b/include/linux/notifier.h
index aef88c2d1173..d5e9c0aea933 100644
--- a/include/linux/notifier.h
+++ b/include/linux/notifier.h
@@ -174,9 +174,13 @@ extern int srcu_notifier_call_chain(struct srcu_notifier_head *nh,
 		unsigned long val, void *v);
 
 extern int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
-		unsigned long val_up, unsigned long val_down, void *v);
+					       unsigned long val_up,
+					       unsigned long val_down,
+					       void *v_up, void *v_down);
 extern int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
-		unsigned long val_up, unsigned long val_down, void *v);
+					  unsigned long val_up,
+					  unsigned long val_down,
+					  void *v_up, void *v_down);
 
 extern bool atomic_notifier_call_chain_is_empty(struct atomic_notifier_head *nh);
 
diff --git a/kernel/cpu_pm.c b/kernel/cpu_pm.c
index ba4ba71facf9..32ca243f0306 100644
--- a/kernel/cpu_pm.c
+++ b/kernel/cpu_pm.c
@@ -51,7 +51,8 @@ static int cpu_pm_notify_robust(enum cpu_pm_event event_up, enum cpu_pm_event ev
 
 	ct_irq_enter_irqson();
 	raw_spin_lock_irqsave(&cpu_pm_notifier.lock, flags);
-	ret = raw_notifier_call_chain_robust(&cpu_pm_notifier.chain, event_up, event_down, NULL);
+	ret = raw_notifier_call_chain_robust(&cpu_pm_notifier.chain, event_up, event_down,
+					     NULL, NULL);
 	raw_spin_unlock_irqrestore(&cpu_pm_notifier.lock, flags);
 	ct_irq_exit_irqson();
 
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 6a477c622544..d92d6e142d11 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -2638,7 +2638,9 @@ static int prepare_coming_module(struct module *mod)
 		return err;
 
 	err = blocking_notifier_call_chain_robust(&module_notify_list,
-			MODULE_STATE_COMING, MODULE_STATE_GOING, mod);
+						  MODULE_STATE_COMING,
+						  MODULE_STATE_GOING,
+						  mod, mod);
 	err = notifier_to_errno(err);
 	if (err)
 		klp_module_going(mod);
diff --git a/kernel/notifier.c b/kernel/notifier.c
index 0d5bd62c480e..db71eb12ad98 100644
--- a/kernel/notifier.c
+++ b/kernel/notifier.c
@@ -114,14 +114,14 @@ NOKPROBE_SYMBOL(notifier_call_chain);
  * Returns:	the return value of the @val_up call.
  */
 static int notifier_call_chain_robust(struct notifier_block **nl,
-				     unsigned long val_up, unsigned long val_down,
-				     void *v)
+				      unsigned long val_up, unsigned long val_down,
+				      void *v_up, void *v_down)
 {
 	int ret, nr = 0;
 
-	ret = notifier_call_chain(nl, val_up, v, -1, &nr);
+	ret = notifier_call_chain(nl, val_up, v_up, -1, &nr);
 	if (ret & NOTIFY_STOP_MASK)
-		notifier_call_chain(nl, val_down, v, nr-1, NULL);
+		notifier_call_chain(nl, val_down, v_down, nr-1, NULL);
 
 	return ret;
 }
@@ -333,7 +333,9 @@ int blocking_notifier_chain_unregister(struct blocking_notifier_head *nh,
 EXPORT_SYMBOL_GPL(blocking_notifier_chain_unregister);
 
 int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
-		unsigned long val_up, unsigned long val_down, void *v)
+					unsigned long val_up,
+					unsigned long val_down, void *v_up,
+					void *v_down)
 {
 	int ret = NOTIFY_DONE;
 
@@ -344,7 +346,8 @@ int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh,
 	 */
 	if (rcu_access_pointer(nh->head)) {
 		down_read(&nh->rwsem);
-		ret = notifier_call_chain_robust(&nh->head, val_up, val_down, v);
+		ret = notifier_call_chain_robust(&nh->head, val_up, val_down,
+						 v_up, v_down);
 		up_read(&nh->rwsem);
 	}
 	return ret;
@@ -426,9 +429,11 @@ int raw_notifier_chain_unregister(struct raw_notifier_head *nh,
 EXPORT_SYMBOL_GPL(raw_notifier_chain_unregister);
 
 int raw_notifier_call_chain_robust(struct raw_notifier_head *nh,
-		unsigned long val_up, unsigned long val_down, void *v)
+				   unsigned long val_up, unsigned long val_down,
+				   void *v_up, void *v_down)
 {
-	return notifier_call_chain_robust(&nh->head, val_up, val_down, v);
+	return notifier_call_chain_robust(&nh->head, val_up, val_down, v_up,
+					  v_down);
 }
 EXPORT_SYMBOL_GPL(raw_notifier_call_chain_robust);
 
diff --git a/kernel/power/main.c b/kernel/power/main.c
index e3694034b753..edc49debbecd 100644
--- a/kernel/power/main.c
+++ b/kernel/power/main.c
@@ -84,7 +84,8 @@ int pm_notifier_call_chain_robust(unsigned long val_up, unsigned long val_down)
 {
 	int ret;
 
-	ret = blocking_notifier_call_chain_robust(&pm_chain_head, val_up, val_down, NULL);
+	ret = blocking_notifier_call_chain_robust(&pm_chain_head, val_up,
+						  val_down, NULL, NULL);
 
 	return notifier_to_errno(ret);
 }
diff --git a/net/core/dev.c b/net/core/dev.c
index 716df64fcfa5..5820f18c2e1d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1968,7 +1968,7 @@ call_netdevice_notifiers_info_robust(unsigned long val_up,
 	ASSERT_RTNL();
 
 	return raw_notifier_call_chain_robust(&net->netdev_chain,
-					      val_up, val_down, info);
+					      val_up, val_down, info, info);
 }
 
 static int call_netdevice_notifiers_extack(unsigned long val,
-- 
2.34.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ