forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
module: Introduce module unload taint tracking
Currently, only the initial module that tainted the kernel is recorded e.g. when an out-of-tree module is loaded. The purpose of this patch is to allow the kernel to maintain a record of each unloaded module that taints the kernel. So, in addition to displaying a list of linked modules (see print_modules()) e.g. in the event of a detected bad page, unloaded modules that carried a taint/or taints are displayed too. A tainted module unload count is maintained. The number of tracked modules is not fixed. This feature is disabled by default. Signed-off-by: Aaron Tomlin <[email protected]> Signed-off-by: Luis Chamberlain <[email protected]>
- Loading branch information
Showing
5 changed files
with
99 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// SPDX-License-Identifier: GPL-2.0-or-later | ||
/* | ||
* Module taint unload tracking support | ||
* | ||
* Copyright (C) 2022 Aaron Tomlin | ||
*/ | ||
|
||
#include <linux/module.h> | ||
#include <linux/string.h> | ||
#include <linux/printk.h> | ||
#include <linux/slab.h> | ||
#include <linux/list.h> | ||
#include <linux/rculist.h> | ||
#include "internal.h" | ||
|
||
static LIST_HEAD(unloaded_tainted_modules); | ||
|
||
int try_add_tainted_module(struct module *mod) | ||
{ | ||
struct mod_unload_taint *mod_taint; | ||
|
||
module_assert_mutex_or_preempt(); | ||
|
||
list_for_each_entry_rcu(mod_taint, &unloaded_tainted_modules, list, | ||
lockdep_is_held(&module_mutex)) { | ||
if (!strcmp(mod_taint->name, mod->name) && | ||
mod_taint->taints & mod->taints) { | ||
mod_taint->count++; | ||
goto out; | ||
} | ||
} | ||
|
||
mod_taint = kmalloc(sizeof(*mod_taint), GFP_KERNEL); | ||
if (unlikely(!mod_taint)) | ||
return -ENOMEM; | ||
strscpy(mod_taint->name, mod->name, MODULE_NAME_LEN); | ||
mod_taint->taints = mod->taints; | ||
list_add_rcu(&mod_taint->list, &unloaded_tainted_modules); | ||
mod_taint->count = 1; | ||
out: | ||
return 0; | ||
} | ||
|
||
void print_unloaded_tainted_modules(void) | ||
{ | ||
struct mod_unload_taint *mod_taint; | ||
char buf[MODULE_FLAGS_BUF_SIZE]; | ||
|
||
if (!list_empty(&unloaded_tainted_modules)) { | ||
printk(KERN_DEFAULT "Unloaded tainted modules:"); | ||
list_for_each_entry_rcu(mod_taint, &unloaded_tainted_modules, | ||
list) { | ||
size_t l; | ||
|
||
l = module_flags_taint(mod_taint->taints, buf); | ||
buf[l++] = '\0'; | ||
pr_cont(" %s(%s):%llu", mod_taint->name, buf, | ||
mod_taint->count); | ||
} | ||
} | ||
} |