* [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc
@ 2026-06-18 16:02 Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 1/3] gpiolib: Extract gpiochip_choose_fwnode() for wider use Quentin Schulz
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Quentin Schulz @ 2026-06-18 16:02 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, Quentin Schulz,
Andy Shevchenko, Mathieu Dubois-Briand, Tzung-Bi Shih, stable,
Linus Walleij, Bartosz Golaszewski
Backport 16fdabe143fc ("gpio: Fix resource leaks on errors in
gpiochip_add_data_with_key()") to 6.12.y. To make the git diff more
similar with the upstream commit, also backport 375790f18396 ("gpiolib:
Extract gpiochip_choose_fwnode() for wider use") and 550300b9a295
("gpiolib: Remove redundant assignment of return variable").
The changes between 16fdabe143fc and the third patch of this series is
(according to git-range-diff):
"""
## drivers/gpio/gpiolib.c ##
@@ drivers/gpio/gpiolib.c: static const struct device_type gpio_dev_type = {
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, voi
+ }
+
+ gdev->can_sleep = gc->can_sleep;
-+ rwlock_init(&gdev->line_state_lock);
-+ RAW_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
++ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
+#ifdef CONFIG_PINCTRL
+ INIT_LIST_HEAD(&gdev->pin_ranges);
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, voi
- gdev->ngpio = gc->ngpio;
- gdev->can_sleep = gc->can_sleep;
-
-- rwlock_init(&gdev->line_state_lock);
-- RAW_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
+- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
-
- ret = init_srcu_struct(&gdev->srcu);
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, voi
@@ drivers/gpio/gpiolib.c: int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiodev_add_to_list_unlocked(gdev);
if (ret) {
- gpiochip_err(gc, "GPIO integer space overlap, cannot add chip\n");
+ chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
"""
s/gpiochip_err/chip_err/ aside, the rest of the diff comes from feature
commits which do not fit the rules for backporting to stable.
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
Andy Shevchenko (2):
gpiolib: Extract gpiochip_choose_fwnode() for wider use
gpiolib: Remove redundant assignment of return variable
Tzung-Bi Shih (1):
gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()
drivers/gpio/gpiolib.c | 156 +++++++++++++++++++++++++------------------------
1 file changed, 79 insertions(+), 77 deletions(-)
---
base-commit: 1d3a00d3bacff25652c96e1527610c69e91f7c38
change-id: 20260618-6-12-cve-2026-31732-63076d516720
Best regards,
--
Quentin Schulz <quentin.schulz@cherry.de>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH 6.12.y 1/3] gpiolib: Extract gpiochip_choose_fwnode() for wider use
2026-06-18 16:02 [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Quentin Schulz
@ 2026-06-18 16:02 ` Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 2/3] gpiolib: Remove redundant assignment of return variable Quentin Schulz
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Quentin Schulz @ 2026-06-18 16:02 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, Quentin Schulz,
Andy Shevchenko, Mathieu Dubois-Briand
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 375790f18396b2ba706e031b150c58cd37b45a11 ]
Extract gpiochip_choose_fwnode() for the future use in another function.
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Tested-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Reviewed-by: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
Link: https://lore.kernel.org/r/20250213195621.3133406-2-andriy.shevchenko@linux.intel.com
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
Stable-dep-of: 16fdabe143fc ("gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 24 ++++++++++++++++--------
1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 5c8cd81656963..d48a57b899f79 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -883,6 +883,21 @@ void *gpiochip_get_data(struct gpio_chip *gc)
}
EXPORT_SYMBOL_GPL(gpiochip_get_data);
+/*
+ * If the calling driver provides the specific firmware node,
+ * use it. Otherwise use the one from the parent device, if any.
+ */
+static struct fwnode_handle *gpiochip_choose_fwnode(struct gpio_chip *gc)
+{
+ if (gc->fwnode)
+ return gc->fwnode;
+
+ if (gc->parent)
+ return dev_fwnode(gc->parent);
+
+ return NULL;
+}
+
int gpiochip_get_ngpios(struct gpio_chip *gc, struct device *dev)
{
u32 ngpios = gc->ngpio;
@@ -942,14 +957,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
gc->gpiodev = gdev;
gpiochip_set_data(gc, data);
- /*
- * If the calling driver did not initialize firmware node,
- * do it here using the parent device, if any.
- */
- if (gc->fwnode)
- device_set_node(&gdev->dev, gc->fwnode);
- else if (gc->parent)
- device_set_node(&gdev->dev, dev_fwnode(gc->parent));
+ device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
if (gdev->id < 0) {
--
2.54.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.12.y 2/3] gpiolib: Remove redundant assignment of return variable
2026-06-18 16:02 [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 1/3] gpiolib: Extract gpiochip_choose_fwnode() for wider use Quentin Schulz
@ 2026-06-18 16:02 ` Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 3/3] gpio: Fix resource leaks on errors in gpiochip_add_data_with_key() Quentin Schulz
2026-06-19 4:07 ` [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Quentin Schulz @ 2026-06-18 16:02 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, Quentin Schulz,
Andy Shevchenko
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 550300b9a295a591e0721a31f8c964a4bc08d51c ]
In some functions the returned variable is assigned to 0 and then
reassigned to the actual value. Remove redundant assignments.
In one case make it more clear that the assignment is not needed.
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://lore.kernel.org/r/20250416095645.2027695-9-andriy.shevchenko@linux.intel.com
Signed-off-by: Bartosz Golaszewski <brgl@bgdev.pl>
Stable-dep-of: 16fdabe143fc ("gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()")
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index d48a57b899f79..97a32e6f901fc 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -939,7 +939,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
struct gpio_device *gdev;
unsigned int desc_index;
int base = 0;
- int ret = 0;
+ int ret;
/*
* First: allocate and populate the internal stat container, and
@@ -959,11 +959,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
- gdev->id = ida_alloc(&gpio_ida, GFP_KERNEL);
- if (gdev->id < 0) {
- ret = gdev->id;
+ ret = ida_alloc(&gpio_ida, GFP_KERNEL);
+ if (ret < 0)
goto err_free_gdev;
- }
+ gdev->id = ret;
ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
if (ret)
@@ -2882,7 +2881,7 @@ EXPORT_SYMBOL_GPL(gpiod_direction_output);
*/
int gpiod_enable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
{
- int ret = 0;
+ int ret;
VALIDATE_DESC(desc);
@@ -2915,7 +2914,7 @@ EXPORT_SYMBOL_GPL(gpiod_enable_hw_timestamp_ns);
*/
int gpiod_disable_hw_timestamp_ns(struct gpio_desc *desc, unsigned long flags)
{
- int ret = 0;
+ int ret;
VALIDATE_DESC(desc);
--
2.54.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH 6.12.y 3/3] gpio: Fix resource leaks on errors in gpiochip_add_data_with_key()
2026-06-18 16:02 [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 1/3] gpiolib: Extract gpiochip_choose_fwnode() for wider use Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 2/3] gpiolib: Remove redundant assignment of return variable Quentin Schulz
@ 2026-06-18 16:02 ` Quentin Schulz
2026-06-19 4:07 ` [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Quentin Schulz @ 2026-06-18 16:02 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: linux-gpio, linux-kernel, Bartosz Golaszewski, Quentin Schulz,
Tzung-Bi Shih, stable, Linus Walleij, Bartosz Golaszewski
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 16fdabe143fce2cbf89139677728e17e21b46c28 ]
Since commit aab5c6f20023 ("gpio: set device type for GPIO chips"),
`gdev->dev.release` is unset. As a result, the reference count to
`gdev->dev` isn't dropped on the error handling paths.
Drop the reference on errors.
Also reorder the instructions to make the error handling simpler.
Now gpiochip_add_data_with_key() roughly looks like:
>>> Some memory allocation. Go to ERR ZONE 1 on errors.
>>> device_initialize().
gpiodev_release() takes over the responsibility for freeing the
resources of `gdev->dev`. The subsequent error handling paths
shouldn't go through ERR ZONE 1 again which leads to double free.
>>> Some initialization mainly on `gdev`.
>>> The rest of initialization. Go to ERR ZONE 2 on errors.
>>> Chip registration success and exit.
>>> ERR ZONE 2. gpio_device_put() and exit.
>>> ERR ZONE 1.
Cc: stable@vger.kernel.org
Fixes: aab5c6f20023 ("gpio: set device type for GPIO chips")
Reviewed-by: Linus Walleij <linusw@kernel.org>
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260205092840.2574840-1-tzungbi@kernel.org
Signed-off-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
[missing commit fcc8b637c542 ("gpiolib: switch the line state notifier
to atomic"), commit dcb73cbaaeb3 ("gpio: cdev: use raw notifier for
line state events") and commit d4f335b410dd ("gpiolib: rename GPIO chip
printk macros") in 6.12.y.
s/gpiochip_err/chip_err/ as well as replaced
rwlock_init+RAW_INIT_NOTIFIER_HEAD with BLOCKING_INIT_NOTIFIER_HEAD
based on missing commits, following same logic as in 16fdabe143fc.]
Signed-off-by: Quentin Schulz <quentin.schulz@cherry.de>
---
drivers/gpio/gpiolib.c | 121 ++++++++++++++++++++++++-------------------------
1 file changed, 58 insertions(+), 63 deletions(-)
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index 97a32e6f901fc..878f9ab4a0982 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -785,13 +785,15 @@ static const struct device_type gpio_dev_type = {
#define gcdev_unregister(gdev) device_del(&(gdev)->dev)
#endif
+/*
+ * An initial reference count has been held in gpiochip_add_data_with_key().
+ * The caller should drop the reference via gpio_device_put() on errors.
+ */
static int gpiochip_setup_dev(struct gpio_device *gdev)
{
struct fwnode_handle *fwnode = dev_fwnode(&gdev->dev);
int ret;
- device_initialize(&gdev->dev);
-
/*
* If fwnode doesn't belong to another device, it's safe to clear its
* initialized flag.
@@ -859,9 +861,11 @@ static void gpiochip_setup_devs(void)
list_for_each_entry_srcu(gdev, &gpio_devices, list,
srcu_read_lock_held(&gpio_devices_srcu)) {
ret = gpiochip_setup_dev(gdev);
- if (ret)
+ if (ret) {
+ gpio_device_put(gdev);
dev_err(&gdev->dev,
"Failed to initialize gpio device (%d)\n", ret);
+ }
}
}
@@ -941,33 +945,64 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
int base = 0;
int ret;
- /*
- * First: allocate and populate the internal stat container, and
- * set up the struct device.
- */
gdev = kzalloc(sizeof(*gdev), GFP_KERNEL);
if (!gdev)
return -ENOMEM;
-
- gdev->dev.type = &gpio_dev_type;
- gdev->dev.bus = &gpio_bus_type;
- gdev->dev.parent = gc->parent;
- rcu_assign_pointer(gdev->chip, gc);
-
gc->gpiodev = gdev;
gpiochip_set_data(gc, data);
- device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
-
ret = ida_alloc(&gpio_ida, GFP_KERNEL);
if (ret < 0)
goto err_free_gdev;
gdev->id = ret;
- ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+ ret = init_srcu_struct(&gdev->srcu);
if (ret)
goto err_free_ida;
+ rcu_assign_pointer(gdev->chip, gc);
+ ret = init_srcu_struct(&gdev->desc_srcu);
+ if (ret)
+ goto err_cleanup_gdev_srcu;
+
+ ret = dev_set_name(&gdev->dev, GPIOCHIP_NAME "%d", gdev->id);
+ if (ret)
+ goto err_cleanup_desc_srcu;
+
+ device_initialize(&gdev->dev);
+ /*
+ * After this point any allocated resources to `gdev` will be
+ * free():ed by gpiodev_release(). If you add new resources
+ * then make sure they get free():ed there.
+ */
+ gdev->dev.type = &gpio_dev_type;
+ gdev->dev.bus = &gpio_bus_type;
+ gdev->dev.parent = gc->parent;
+ device_set_node(&gdev->dev, gpiochip_choose_fwnode(gc));
+
+ ret = gpiochip_get_ngpios(gc, &gdev->dev);
+ if (ret)
+ goto err_put_device;
+ gdev->ngpio = gc->ngpio;
+
+ gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
+ if (!gdev->descs) {
+ ret = -ENOMEM;
+ goto err_put_device;
+ }
+
+ gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
+ if (!gdev->label) {
+ ret = -ENOMEM;
+ goto err_put_device;
+ }
+
+ gdev->can_sleep = gc->can_sleep;
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
+ BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
+#ifdef CONFIG_PINCTRL
+ INIT_LIST_HEAD(&gdev->pin_ranges);
+#endif
if (gc->parent && gc->parent->driver)
gdev->owner = gc->parent->driver->owner;
else if (gc->owner)
@@ -976,36 +1011,6 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
else
gdev->owner = THIS_MODULE;
- ret = gpiochip_get_ngpios(gc, &gdev->dev);
- if (ret)
- goto err_free_dev_name;
-
- gdev->descs = kcalloc(gc->ngpio, sizeof(*gdev->descs), GFP_KERNEL);
- if (!gdev->descs) {
- ret = -ENOMEM;
- goto err_free_dev_name;
- }
-
- gdev->label = kstrdup_const(gc->label ?: "unknown", GFP_KERNEL);
- if (!gdev->label) {
- ret = -ENOMEM;
- goto err_free_descs;
- }
-
- gdev->ngpio = gc->ngpio;
- gdev->can_sleep = gc->can_sleep;
-
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->line_state_notifier);
- BLOCKING_INIT_NOTIFIER_HEAD(&gdev->device_notifier);
-
- ret = init_srcu_struct(&gdev->srcu);
- if (ret)
- goto err_free_label;
-
- ret = init_srcu_struct(&gdev->desc_srcu);
- if (ret)
- goto err_cleanup_gdev_srcu;
-
scoped_guard(mutex, &gpio_devices_lock) {
/*
* TODO: this allocates a Linux GPIO number base in the global
@@ -1020,7 +1025,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
if (base < 0) {
ret = base;
base = 0;
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
/*
@@ -1040,14 +1045,10 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
ret = gpiodev_add_to_list_unlocked(gdev);
if (ret) {
chip_err(gc, "GPIO integer space overlap, cannot add chip\n");
- goto err_cleanup_desc_srcu;
+ goto err_put_device;
}
}
-#ifdef CONFIG_PINCTRL
- INIT_LIST_HEAD(&gdev->pin_ranges);
-#endif
-
if (gc->names)
gpiochip_set_desc_names(gc);
@@ -1128,25 +1129,19 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,
scoped_guard(mutex, &gpio_devices_lock)
list_del_rcu(&gdev->list);
synchronize_srcu(&gpio_devices_srcu);
- if (gdev->dev.release) {
- /* release() has been registered by gpiochip_setup_dev() */
- gpio_device_put(gdev);
- goto err_print_message;
- }
+err_put_device:
+ gpio_device_put(gdev);
+ goto err_print_message;
+
err_cleanup_desc_srcu:
cleanup_srcu_struct(&gdev->desc_srcu);
err_cleanup_gdev_srcu:
cleanup_srcu_struct(&gdev->srcu);
-err_free_label:
- kfree_const(gdev->label);
-err_free_descs:
- kfree(gdev->descs);
-err_free_dev_name:
- kfree(dev_name(&gdev->dev));
err_free_ida:
ida_free(&gpio_ida, gdev->id);
err_free_gdev:
kfree(gdev);
+
err_print_message:
/* failures here can mean systems won't boot... */
if (ret != -EPROBE_DEFER) {
--
2.54.0
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc
2026-06-18 16:02 [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Quentin Schulz
` (2 preceding siblings ...)
2026-06-18 16:02 ` [PATCH 6.12.y 3/3] gpio: Fix resource leaks on errors in gpiochip_add_data_with_key() Quentin Schulz
@ 2026-06-19 4:07 ` Sasha Levin
3 siblings, 0 replies; 5+ messages in thread
From: Sasha Levin @ 2026-06-19 4:07 UTC (permalink / raw)
To: Linus Walleij, Bartosz Golaszewski, Greg Kroah-Hartman
Cc: Sasha Levin, linux-gpio, linux-kernel, Bartosz Golaszewski,
Quentin Schulz, Andy Shevchenko, Mathieu Dubois-Briand,
Tzung-Bi Shih, stable, Linus Walleij, Bartosz Golaszewski,
Quentin Schulz
> [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc (gpio: Fix resource
> leaks on errors in gpiochip_add_data_with_key()) - CVE-2026-31732
Queued the series for 6.12, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-06-19 4:07 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-18 16:02 [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 1/3] gpiolib: Extract gpiochip_choose_fwnode() for wider use Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 2/3] gpiolib: Remove redundant assignment of return variable Quentin Schulz
2026-06-18 16:02 ` [PATCH 6.12.y 3/3] gpio: Fix resource leaks on errors in gpiochip_add_data_with_key() Quentin Schulz
2026-06-19 4:07 ` [PATCH 6.12.y 0/3] gpiolib: backport 16fdabe143fc Sasha Levin
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.