Module Name: src Committed By: riastradh Date: Fri Aug 12 15:17:10 UTC 2022
Modified Files: src/sys/kern: kern_module.c Log Message: module(9): Don't autounload unaudited modules by default. Modules that have not been audited for autounload safety don't recognize the command MODULE_CMD_AUTOUNLOAD and return ENOTTY. These modules are not safe to autounload, so don't autounload them. Since unload is risky business (if not careful, can lead to use-after-free, kernel memory corruption, &c.), it needs to be opt-in by default, not opt-out. Modules that have been audited can return 0 or EBUSY to explicitly allow or deny autounload. Users who want to live on the edge to try to exercise module autounload even for unaudited modules -- and are willing to accept the consequences, and maybe contribute to auditing! -- can set the new sysctl knob kern.module.autounload_unsafe=1. Discussed on tech-kern: https://mail-index.netbsd.org/tech-kern/2022/08/08/msg028282.html To generate a diff of this commit: cvs rdiff -u -r1.157 -r1.158 src/sys/kern/kern_module.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/kern_module.c diff -u src/sys/kern/kern_module.c:1.157 src/sys/kern/kern_module.c:1.158 --- src/sys/kern/kern_module.c:1.157 Sun Aug 7 23:03:59 2022 +++ src/sys/kern/kern_module.c Fri Aug 12 15:17:10 2022 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_module.c,v 1.157 2022/08/07 23:03:59 riastradh Exp $ */ +/* $NetBSD: kern_module.c,v 1.158 2022/08/12 15:17:10 riastradh Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -34,7 +34,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.157 2022/08/07 23:03:59 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_module.c,v 1.158 2022/08/12 15:17:10 riastradh Exp $"); #define _MODULE_INTERNAL @@ -94,6 +94,7 @@ bool module_autoload_on = true; #else bool module_autoload_on = false; #endif +bool module_autounload_unsafe = 0; u_int module_count; u_int module_builtinlist; u_int module_autotime = 10; @@ -546,6 +547,12 @@ sysctl_module_setup(void) CTL_CREATE, CTL_EOL); sysctl_createv(&module_sysctllog, 0, &node, NULL, CTLFLAG_PERMANENT | CTLFLAG_READWRITE, + CTLTYPE_BOOL, "autounload_unsafe", + SYSCTL_DESCR("Enable automatic unload of unaudited modules"), + NULL, 0, &module_autounload_unsafe, 0, + CTL_CREATE, CTL_EOL); + sysctl_createv(&module_sysctllog, 0, &node, NULL, + CTLFLAG_PERMANENT | CTLFLAG_READWRITE, CTLTYPE_BOOL, "verbose", SYSCTL_DESCR("Enable verbose output"), NULL, 0, &module_verbose_on, 0, @@ -1672,14 +1679,28 @@ module_thread(void *cookie) } /* - * If this module wants to avoid autounload then - * skip it. Some modules can ping-pong in and out - * because their use is transient but often. - * Example: exec_script. + * Ask the module if it can be safely unloaded. + * + * - Modules which have been audited to be OK + * with that will return 0. + * + * - Modules which have not been audited for + * safe autounload will return ENOTTY. + * + * => With kern.module.autounload_unsafe=1, + * we treat ENOTTY as acceptance. + * + * - Some modules would ping-ping in and out + * because their use is transient but often. + * Example: exec_script. Other modules may + * still be in use. These modules can + * prevent autounload in all cases by + * returning EBUSY or some other error code. */ mi = mod->mod_info; error = (*mi->mi_modcmd)(MODULE_CMD_AUTOUNLOAD, NULL); - if (error == 0 || error == ENOTTY) { + if (error == 0 || + (error == ENOTTY && module_autounload_unsafe)) { (void)module_do_unload(mi->mi_name, false); } else module_print("module `%s' declined to be "