kernel/module/main.c
Source file repositories/reference/linux-study-clean/kernel/module/main.c
File Facts
- System
- Linux kernel
- Corpus path
kernel/module/main.c- Extension
.c- Size
- 103862 bytes
- Lines
- 3989
- Domain
- Core OS
- Bucket
- Scheduler, Processes, Timers, Sync, And Syscalls
- Inferred role
- Core OS: syscall or user/kernel boundary
- Status
- core implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Defines or participates in a user/kernel boundary; inspect argument validation, copy_from_user/copy_to_user, credentials, and dispatch target.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/export.hlinux/extable.hlinux/moduleloader.hlinux/module_signature.hlinux/module_symbol.hlinux/trace_events.hlinux/init.hlinux/kallsyms.hlinux/buildid.hlinux/fs.hlinux/kernel.hlinux/kernel_read_file.hlinux/kstrtox.hlinux/slab.hlinux/vmalloc.hlinux/elf.hlinux/seq_file.hlinux/syscalls.hlinux/fcntl.hlinux/rcupdate.hlinux/capability.hlinux/cpu.hlinux/moduleparam.hlinux/errno.hlinux/err.hlinux/vermagic.hlinux/notifier.hlinux/sched.hlinux/device.hlinux/string.hlinux/mutex.hlinux/rculist.h
Detected Declarations
syscall delete_modulesyscall init_modulesyscall finit_modulestruct symsearchstruct mod_initfreestruct idempotentfunction __mod_update_boundsfunction mod_update_boundsfunction init_module_sysctlfunction register_module_notifierfunction unregister_module_notifierfunction try_module_getfunction add_taint_modulefunction strncmpfunction __module_put_and_kthread_exitfunction find_secfunction find_any_unique_secfunction find_any_secfunction cmp_namefunction find_exported_symbol_in_sectionfunction find_symbolfunction list_for_each_entry_rcufunction list_for_each_entry_rcufunction percpu_modallocfunction percpu_modfreefunction find_pcpusecfunction percpu_modcopyfunction __is_module_percpu_addressfunction for_each_possible_cpufunction is_module_percpu_addressfunction percpu_modallocfunction percpu_modfreefunction percpu_modcopyfunction is_module_percpu_addressfunction __is_module_percpu_addressfunction setup_modinfo_import_nsfunction show_modinfo_import_nsfunction modinfo_import_ns_existsfunction free_modinfo_import_nsfunction module_unload_initfunction already_usesfunction list_for_each_entryfunction targetsfunction ref_modulefunction module_unload_freefunction try_force_unloadfunction try_force_unloadfunction try_release_module_ref
Annotated Snippet
SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)
{
struct module *mod;
char name[MODULE_NAME_LEN];
char buf[MODULE_FLAGS_BUF_SIZE];
int ret, len, forced = 0;
if (!capable(CAP_SYS_MODULE) || modules_disabled)
return -EPERM;
len = strncpy_from_user(name, name_user, MODULE_NAME_LEN);
if (len == 0 || len == MODULE_NAME_LEN)
return -ENOENT;
if (len < 0)
return len;
audit_log_kern_module(name);
if (mutex_lock_interruptible(&module_mutex) != 0)
return -EINTR;
mod = find_module(name);
if (!mod) {
ret = -ENOENT;
goto out;
}
if (!list_empty(&mod->source_list)) {
/* Other modules depend on us: get rid of them first. */
ret = -EWOULDBLOCK;
goto out;
}
/* Doing init or already dying? */
if (mod->state != MODULE_STATE_LIVE) {
/* FIXME: if (force), slam module count damn the torpedoes */
pr_debug("%s already dying\n", mod->name);
ret = -EBUSY;
goto out;
}
/* If it has an init func, it must have an exit func to unload */
if (mod->init && !mod->exit) {
forced = try_force_unload(flags);
if (!forced) {
/* This module can't be removed */
ret = -EBUSY;
goto out;
}
}
ret = try_stop_module(mod, flags, &forced);
if (ret != 0)
goto out;
mutex_unlock(&module_mutex);
/* Final destruction now no one is using it. */
if (mod->exit != NULL)
mod->exit();
blocking_notifier_call_chain(&module_notify_list,
MODULE_STATE_GOING, mod);
klp_module_going(mod);
ftrace_release_mod(mod);
async_synchronize_full();
/* Store the name and taints of the last unloaded module for diagnostic purposes */
strscpy(last_unloaded_module.name, mod->name);
strscpy(last_unloaded_module.taints, module_flags(mod, buf, false));
free_module(mod);
/* someone could wait for the module in add_unformed_module() */
wake_up_all(&module_wq);
return 0;
out:
mutex_unlock(&module_mutex);
return ret;
}
void __symbol_put(const char *symbol)
{
struct find_symbol_arg fsa = {
.name = symbol,
.gplok = true,
};
guard(rcu)();
BUG_ON(!find_symbol(&fsa));
module_put(fsa.owner);
Annotation
- Immediate include surface: `linux/export.h`, `linux/extable.h`, `linux/moduleloader.h`, `linux/module_signature.h`, `linux/module_symbol.h`, `linux/trace_events.h`, `linux/init.h`, `linux/kallsyms.h`.
- Detected declarations: `syscall delete_module`, `syscall init_module`, `syscall finit_module`, `struct symsearch`, `struct mod_initfree`, `struct idempotent`, `function __mod_update_bounds`, `function mod_update_bounds`, `function init_module_sysctl`, `function register_module_notifier`.
- Atlas domain: Core OS / Scheduler, Processes, Timers, Sync, And Syscalls.
- Implementation status: core implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.