[PATCH v1] pps: generators: Pin dummy provider while a file is open

Yibo Tan posted 1 patch 1 week, 6 days ago
Documentation/driver-api/pps.rst       | 1 +
drivers/pps/generators/pps_gen-dummy.c | 1 +
2 files changed, 2 insertions(+)
[PATCH v1] pps: generators: Pin dummy provider while a file is open
Posted by Yibo Tan 1 week, 6 days ago
pps_gen_register_cdev() copies pps_gen_source_info.owner to cdev.owner so
an open file pins the module that owns provider metadata and callbacks. The
dummy generator leaves owner unset, allowing pps_gen_dummy to unload while
an old file remains usable through pps_gen_core.

The old file retains the core-owned pps_gen_device, whose info pointer then
refers to unloaded pps_gen_dummy rodata. PPS_GEN_SETENABLE dereferences the
stale info->enable member and may call through memory reused by another
module.

In three KASAN runs, a uid-65534 process with no capabilities held the old
file while a separate root process unloaded the dummy provider. The later
ioctl faulted in pps_gen_cdev_ioctl(). A stock-module follow-up also
reproduced three kernel panics after the same uid-65534 process naturally
autoloaded can-bcm.ko into the retired rodata page and reached a NULL call.
The administrator-performed provider unload remains a prerequisite.

Set owner to THIS_MODULE and update the documentation example. In three
owner-only fixed runs, the open file raised the provider refcount, unload
failed with EAGAIN, and the ioctl, close, and subsequent unload completed
without a kernel diagnostic.

Fixes: 580afe4acbd4 ("drivers pps/generators: add dummy PPS generator")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Yibo Tan <lhfff@tju.edu.cn>
---
 Documentation/driver-api/pps.rst       | 1 +
 drivers/pps/generators/pps_gen-dummy.c | 1 +
 2 files changed, 2 insertions(+)

diff --git a/Documentation/driver-api/pps.rst b/Documentation/driver-api/pps.rst
index 598729f9c..89a473be7 100644
--- a/Documentation/driver-api/pps.rst
+++ b/Documentation/driver-api/pps.rst
@@ -207,6 +207,7 @@ registered in the kernel by defining a struct pps_gen_source_info as
 follows::
 
     static const struct pps_gen_source_info pps_gen_dummy_info = {
+            .owner                  = THIS_MODULE,
             .use_system_clock       = true,
             .get_time               = pps_gen_dummy_get_time,
             .enable                 = pps_gen_dummy_enable,
diff --git a/drivers/pps/generators/pps_gen-dummy.c b/drivers/pps/generators/pps_gen-dummy.c
index a4395543c..393c44246 100644
--- a/drivers/pps/generators/pps_gen-dummy.c
+++ b/drivers/pps/generators/pps_gen-dummy.c
@@ -58,6 +58,7 @@ static int pps_gen_dummy_enable(struct pps_gen_device *pps_gen, bool enable)
  */
 
 static const struct pps_gen_source_info pps_gen_dummy_info = {
+	.owner			= THIS_MODULE,
 	.use_system_clock	= true,
 	.get_time		= pps_gen_dummy_get_time,
 	.enable			= pps_gen_dummy_enable,
-- 
2.39.5