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]
Message-Id: <20230812194457.6432-2-brgl@bgdev.pl>
Date:   Sat, 12 Aug 2023 21:44:54 +0200
From:   Bartosz Golaszewski <brgl@...ev.pl>
To:     Yury Norov <yury.norov@...il.com>,
        Andy Shevchenko <andriy.shevchenko@...ux.intel.com>,
        Rasmus Villemoes <linux@...musvillemoes.dk>,
        Thomas Gleixner <tglx@...utronix.de>
Cc:     linux-kernel@...r.kernel.org,
        Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
Subject: [PATCH 1/4] genirq/irq_sim: dispose of remaining mappings before removing the domain

From: Bartosz Golaszewski <bartosz.golaszewski@...aro.org>

If the device providing simulated interrupts is unbound (real life
example: gpio-sim is disabled with users that didn't free their irqs)
and removes the simulated domain while interrupts are still requested,
we will hit memory issues when they are eventually freed and the
mappings destroyed in the process.

Specifically we'll access freed memory in __irq_domain_deactivate_irq().

Dispose of all mappings before removing the simulator domain.

Fixes: b19af510e67e ("genirq/irq_sim: Add a simple interrupt simulator framework")
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@...aro.org>
---
 kernel/irq/irq_sim.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/irq/irq_sim.c b/kernel/irq/irq_sim.c
index dd76323ea3fd..2c8a9cc1faa6 100644
--- a/kernel/irq/irq_sim.c
+++ b/kernel/irq/irq_sim.c
@@ -4,6 +4,7 @@
  * Copyright (C) 2020 Bartosz Golaszewski <bgolaszewski@...libre.com>
  */
 
+#include <linux/list.h>
 #include <linux/irq.h>
 #include <linux/irq_sim.h>
 #include <linux/irq_work.h>
@@ -16,12 +17,14 @@ struct irq_sim_work_ctx {
 	unsigned int		irq_count;
 	unsigned long		*pending;
 	struct irq_domain	*domain;
+	struct list_head	irqs;
 };
 
 struct irq_sim_irq_ctx {
 	int			irqnum;
 	bool			enabled;
 	struct irq_sim_work_ctx	*work_ctx;
+	struct list_head	siblings;
 };
 
 static void irq_sim_irqmask(struct irq_data *data)
@@ -129,6 +132,8 @@ static int irq_sim_domain_map(struct irq_domain *domain,
 	irq_set_handler(virq, handle_simple_irq);
 	irq_modify_status(virq, IRQ_NOREQUEST | IRQ_NOAUTOEN, IRQ_NOPROBE);
 	irq_ctx->work_ctx = work_ctx;
+	irq_ctx->irqnum = virq;
+	list_add_tail(&irq_ctx->siblings, &work_ctx->irqs);
 
 	return 0;
 }
@@ -141,6 +146,7 @@ static void irq_sim_domain_unmap(struct irq_domain *domain, unsigned int virq)
 	irqd = irq_domain_get_irq_data(domain, virq);
 	irq_ctx = irq_data_get_irq_chip_data(irqd);
 
+	list_del(&irq_ctx->siblings);
 	irq_set_handler(virq, NULL);
 	irq_domain_reset_irq_data(irqd);
 	kfree(irq_ctx);
@@ -182,6 +188,7 @@ struct irq_domain *irq_domain_create_sim(struct fwnode_handle *fwnode,
 
 	work_ctx->irq_count = num_irqs;
 	work_ctx->work = IRQ_WORK_INIT_HARD(irq_sim_handle_irq);
+	INIT_LIST_HEAD(&work_ctx->irqs);
 
 	return work_ctx->domain;
 
@@ -203,8 +210,13 @@ EXPORT_SYMBOL_GPL(irq_domain_create_sim);
 void irq_domain_remove_sim(struct irq_domain *domain)
 {
 	struct irq_sim_work_ctx *work_ctx = domain->host_data;
+	struct irq_sim_irq_ctx *irq_ctx, *aux;
 
 	irq_work_sync(&work_ctx->work);
+
+	list_for_each_entry_safe(irq_ctx, aux, &work_ctx->irqs, siblings)
+		irq_dispose_mapping(irq_ctx->irqnum);
+
 	bitmap_free(work_ctx->pending);
 	kfree(work_ctx);
 
-- 
2.39.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ