From f79848804f6b255e4d50f3fa33f9b52b44bc1f07 Mon Sep 17 00:00:00 2001 From: Kuan-Wei Chiu Date: Thu, 18 Sep 2025 22:19:38 +0800 Subject: [PATCH] Fix incorrect conditional usage of .owner The examples code wrapped .owner = THIS_MODULE inside version checks, suggesting that it is no longer needed after v6.4. This is only true for driver types where the driver core sets .owner automatically (e.g. platform and i2c drivers). For structures such as struct file_operations, .owner must still be set explicitly by the user. Without it, module reference counting will be broken, allowing a module to be unloaded while still in use, which can lead to kernel panics. struct class is a special case: its .owner field was removed in upstream Linux commit 6e30a66433af ("driver core: class: remove struct module owner out of struct class"). Explicitly setting .owner for struct class is safe on older kernels but must be conditionally compiled out on newer kernels. Remove the unnecessary version guards and unconditionally sets .owner = THIS_MODULE in the affected example code. Closes: https://github.com/sysprog21/lkmpg/issues/348 --- examples/dht11.c | 6 +----- examples/ioctl.c | 2 -- examples/static_key.c | 2 -- examples/vinput.c | 5 +++-- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/examples/dht11.c b/examples/dht11.c index 703ecac5..ebf67d12 100644 --- a/examples/dht11.c +++ b/examples/dht11.c @@ -148,12 +148,10 @@ static ssize_t device_read(struct file *filp, char __user *buffer, } static struct file_operations fops = { -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) .owner = THIS_MODULE, -#endif .open = device_open, .release = device_release, - .read = device_read + .read = device_read, }; /* Initialize the module - Register the character device */ @@ -182,9 +180,7 @@ static int __init dht11_init(void) MINOR(dht11_device.dev_num)); /* Prevents module unloading while operations are in use */ -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) dht11_device.cdev.owner = THIS_MODULE; -#endif cdev_init(&dht11_device.cdev, &fops); ret = cdev_add(&dht11_device.cdev, dht11_device.dev_num, 1); diff --git a/examples/ioctl.c b/examples/ioctl.c index f246943e..123b3c8f 100644 --- a/examples/ioctl.c +++ b/examples/ioctl.c @@ -140,9 +140,7 @@ static int test_ioctl_open(struct inode *inode, struct file *filp) } static struct file_operations fops = { -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) .owner = THIS_MODULE, -#endif .open = test_ioctl_open, .release = test_ioctl_close, .read = test_ioctl_read, diff --git a/examples/static_key.c b/examples/static_key.c index b7be8e19..beb11751 100644 --- a/examples/static_key.c +++ b/examples/static_key.c @@ -41,9 +41,7 @@ static struct class *cls; static DEFINE_STATIC_KEY_FALSE(fkey); static struct file_operations chardev_fops = { -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) .owner = THIS_MODULE, -#endif .open = device_open, .release = device_release, .read = device_read, diff --git a/examples/vinput.c b/examples/vinput.c index 1b0a6bad..e624b1c0 100644 --- a/examples/vinput.c +++ b/examples/vinput.c @@ -133,9 +133,7 @@ static ssize_t vinput_write(struct file *file, const char __user *buffer, } static const struct file_operations vinput_fops = { -#if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) .owner = THIS_MODULE, -#endif .open = vinput_open, .release = vinput_release, .read = vinput_read, @@ -337,6 +335,9 @@ ATTRIBUTE_GROUPS(vinput_class); static struct class vinput_class = { .name = "vinput", +/* .owner was removed in Linux v6.4 via upstream commit 6e30a66433af ("driver core: class: remove + * struct module owner out of struct class") + */ #if LINUX_VERSION_CODE < KERNEL_VERSION(6, 4, 0) .owner = THIS_MODULE, #endif