|
10 | 10 | #include <linux/printk.h>
|
11 | 11 | #include <linux/slab.h>
|
12 | 12 | #include <linux/list.h>
|
| 13 | +#include <linux/debugfs.h> |
13 | 14 | #include <linux/rculist.h>
|
14 | 15 | #include "internal.h"
|
15 | 16 |
|
@@ -59,3 +60,70 @@ void print_unloaded_tainted_modules(void)
|
59 | 60 | }
|
60 | 61 | }
|
61 | 62 | }
|
| 63 | + |
| 64 | +#ifdef CONFIG_DEBUG_FS |
| 65 | +static void *unloaded_tainted_modules_seq_start(struct seq_file *m, loff_t *pos) |
| 66 | + __acquires(rcu) |
| 67 | +{ |
| 68 | + rcu_read_lock(); |
| 69 | + return seq_list_start_rcu(&unloaded_tainted_modules, *pos); |
| 70 | +} |
| 71 | + |
| 72 | +static void *unloaded_tainted_modules_seq_next(struct seq_file *m, void *p, loff_t *pos) |
| 73 | +{ |
| 74 | + return seq_list_next_rcu(p, &unloaded_tainted_modules, pos); |
| 75 | +} |
| 76 | + |
| 77 | +static void unloaded_tainted_modules_seq_stop(struct seq_file *m, void *p) |
| 78 | + __releases(rcu) |
| 79 | +{ |
| 80 | + rcu_read_unlock(); |
| 81 | +} |
| 82 | + |
| 83 | +static int unloaded_tainted_modules_seq_show(struct seq_file *m, void *p) |
| 84 | +{ |
| 85 | + struct mod_unload_taint *mod_taint; |
| 86 | + char buf[MODULE_FLAGS_BUF_SIZE]; |
| 87 | + size_t l; |
| 88 | + |
| 89 | + mod_taint = list_entry(p, struct mod_unload_taint, list); |
| 90 | + l = module_flags_taint(mod_taint->taints, buf); |
| 91 | + buf[l++] = '\0'; |
| 92 | + |
| 93 | + seq_printf(m, "%s (%s) %llu", mod_taint->name, buf, mod_taint->count); |
| 94 | + seq_puts(m, "\n"); |
| 95 | + |
| 96 | + return 0; |
| 97 | +} |
| 98 | + |
| 99 | +static const struct seq_operations unloaded_tainted_modules_seq_ops = { |
| 100 | + .start = unloaded_tainted_modules_seq_start, |
| 101 | + .next = unloaded_tainted_modules_seq_next, |
| 102 | + .stop = unloaded_tainted_modules_seq_stop, |
| 103 | + .show = unloaded_tainted_modules_seq_show, |
| 104 | +}; |
| 105 | + |
| 106 | +static int unloaded_tainted_modules_open(struct inode *inode, struct file *file) |
| 107 | +{ |
| 108 | + return seq_open(file, &unloaded_tainted_modules_seq_ops); |
| 109 | +} |
| 110 | + |
| 111 | +static const struct file_operations unloaded_tainted_modules_fops = { |
| 112 | + .open = unloaded_tainted_modules_open, |
| 113 | + .read = seq_read, |
| 114 | + .llseek = seq_lseek, |
| 115 | + .release = seq_release, |
| 116 | +}; |
| 117 | + |
| 118 | +static int __init unloaded_tainted_modules_init(void) |
| 119 | +{ |
| 120 | + struct dentry *dir; |
| 121 | + |
| 122 | + dir = debugfs_create_dir("modules", NULL); |
| 123 | + debugfs_create_file("unloaded_tainted", 0444, dir, NULL, |
| 124 | + &unloaded_tainted_modules_fops); |
| 125 | + |
| 126 | + return 0; |
| 127 | +} |
| 128 | +module_init(unloaded_tainted_modules_init); |
| 129 | +#endif /* CONFIG_DEBUG_FS */ |
0 commit comments