diff options
| author | Xion Wang <xion.wang@mediatek.com> | 2025-09-04 09:37:04 +0300 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2025-11-13 23:34:20 +0300 |
| commit | e9f66c989de4976ed29fcb32b6045bcdba07d396 (patch) | |
| tree | e2ad7c45d19954807e3ceb76a68f3368f58a81e8 /drivers/char/misc.c | |
| parent | 20d15d76605fd2680c276882a54405e8cfe09614 (diff) | |
| download | linux-e9f66c989de4976ed29fcb32b6045bcdba07d396.tar.xz | |
char: Use list_del_init() in misc_deregister() to reinitialize list pointer
[ Upstream commit e28022873c0d051e980c4145f1965cab5504b498 ]
Currently, misc_deregister() uses list_del() to remove the device
from the list. After list_del(), the list pointers are set to
LIST_POISON1 and LIST_POISON2, which may help catch use-after-free bugs,
but does not reset the list head.
If misc_deregister() is called more than once on the same device,
list_empty() will not return true, and list_del() may be called again,
leading to undefined behavior.
Replace list_del() with list_del_init() to reinitialize the list head
after deletion. This makes the code more robust against double
deregistration and allows safe usage of list_empty() on the miscdevice
after deregistration.
[ Note, this seems to keep broken out-of-tree drivers from doing foolish
things. While this does not matter for any in-kernel drivers,
external drivers could use a bit of help to show them they shouldn't
be doing stuff like re-registering misc devices - gregkh ]
Signed-off-by: Xion Wang <xion.wang@mediatek.com>
Link: https://lore.kernel.org/r/20250904063714.28925-2-xion.wang@mediatek.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/char/misc.c')
| -rw-r--r-- | drivers/char/misc.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/drivers/char/misc.c b/drivers/char/misc.c index 6f9ce6b3cc5a..792a1412faff 100644 --- a/drivers/char/misc.c +++ b/drivers/char/misc.c @@ -299,7 +299,7 @@ void misc_deregister(struct miscdevice *misc) return; mutex_lock(&misc_mtx); - list_del(&misc->list); + list_del_init(&misc->list); device_destroy(&misc_class, MKDEV(MISC_MAJOR, misc->minor)); misc_minor_free(misc->minor); if (misc->minor > MISC_DYNAMIC_MINOR) |
