Skip to content

Commit a8b4ed3

Browse files
committed
nice output
1 parent 6cf289e commit a8b4ed3

File tree

1 file changed

+192
-94
lines changed

1 file changed

+192
-94
lines changed

module/procowner.c

100644100755
Lines changed: 192 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -4,132 +4,230 @@
44
#include <linux/seq_file.h>
55
#include <linux/kallsyms.h>
66
#include <linux/rwlock.h>
7+
#include <asm/uaccess.h>
78

8-
#define MOD "[proc-owner]: "
9-
10-
int (*xlate)(const char *name, struct proc_dir_entry **ret, const char **residual);
11-
struct proc_dir_entry* (*subdir_find)(struct proc_dir_entry *dir, const char *name, unsigned int len);
12-
void* subdir_lock;
13-
const char *(*syms_lookup)(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char **modname, char *namebuf);
14-
int (*symbol_name)(unsigned long addr, char *symname);
15-
16-
struct proc_dir_entry {
17-
unsigned int low_ino;
18-
umode_t mode;
19-
nlink_t nlink;
20-
kuid_t uid;
21-
kgid_t gid;
22-
loff_t size;
23-
const struct inode_operations *proc_iops;
24-
const struct file_operations *proc_fops;
25-
struct proc_dir_entry *parent;
26-
struct rb_root subdir;
27-
struct rb_node subdir_node;
28-
void *data;
29-
atomic_t count; /* use count */
30-
atomic_t in_use; /* number of callers into module in progress; */
31-
/* negative -> it's going away RSN */
32-
struct completion *pde_unload_completion;
33-
struct list_head pde_openers; /* who did ->open, but not ->release */
34-
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
35-
u8 namelen;
36-
char name[];
9+
#define MOD "[proc-details]: "
10+
11+
static struct {
12+
char filename[256];
13+
struct proc_dir_entry *dir_entry;
14+
char modname[128];
15+
char fops[128];
16+
char fops_open[128];
17+
char fops_release[128];
18+
char fops_read[128];
19+
char fops_write[128];
20+
char fops_llseek[128];
21+
} proc_details;
22+
23+
static int (*xlate)(const char *name, struct proc_dir_entry **ret, const char **residual);
24+
static struct proc_dir_entry* (*subdir_find)(struct proc_dir_entry *dir, const char *name, unsigned int len);
25+
static void* subdir_lock;
26+
static const char *(*syms_lookup)(unsigned long addr, unsigned long *symbolsize, unsigned long *offset, char **modname, char *namebuf);
27+
static int (*symbol_name)(unsigned long addr, char *symname);
28+
29+
static void get_details(void);
30+
31+
32+
// ----------------------------------------------------------------------------------------------------------
33+
struct proc_dir_entry {
34+
unsigned int low_ino;
35+
umode_t mode;
36+
nlink_t nlink;
37+
kuid_t uid;
38+
kgid_t gid;
39+
loff_t size;
40+
const struct inode_operations *proc_iops;
41+
const struct file_operations *proc_fops;
42+
struct proc_dir_entry *parent;
43+
struct rb_root subdir;
44+
struct rb_node subdir_node;
45+
void *data;
46+
atomic_t count; /* use count */
47+
atomic_t in_use; /* number of callers into module in progress; */
48+
/* negative -> it's going away RSN */
49+
struct completion *pde_unload_completion;
50+
struct list_head pde_openers; /* who did ->open, but not ->release */
51+
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
52+
u8 namelen;
53+
char name[];
3754
};
3855

56+
// ----------------------------------------------------------------------------------------------------------
57+
#define BUF 1024
58+
#define SHOW_FUNCTION(fnc) if(proc_details.fops_##fnc[0]) snprintf(buf, BUF, "%s .%s = %s,\n", buf, #fnc, proc_details.fops_##fnc);
59+
static int proc_procreadwrite_show (struct seq_file *m, void *v) {
60+
size_t i, spacing;
61+
char buf[BUF];
62+
char spacing_left[] = " ";
63+
const char* padding = " ";
64+
int pad = 45;
65+
66+
spacing = (60 - strlen(proc_details.filename) - 6) / 2;
67+
if(spacing < 0 || spacing >= 60) {
68+
spacing = 0;
69+
}
70+
spacing_left[spacing] = 0;
71+
72+
snprintf(buf, BUF, "------------------------------------------------------------\n%s/proc/%s\n------------------------------------------------------------\n", spacing_left, proc_details.filename);
73+
74+
snprintf(buf, BUF, "%s> %s%*.*s : %s\n", buf, "Module ", pad - 8, pad - 8, padding, proc_details.modname);
75+
snprintf(buf, BUF, "%s> %s%*.*s\n", buf, "Mode ");
76+
snprintf(buf, BUF, "%s %s%*.*s : %o\n", buf, "Format ", pad - 12, pad - 12, padding, (proc_details.dir_entry->mode & 0170000) / (8*8*8));
77+
snprintf(buf, BUF, "%s %s%*.*s : %o\n", buf, "Permissions ", pad - 17, pad - 17, padding, proc_details.dir_entry->mode & 0777);
78+
snprintf(buf, BUF, "%s> %s%*.*s : %d\n", buf, "Count ", pad - 7, pad - 7, padding, proc_details.dir_entry->count);
79+
snprintf(buf, BUF, "%s> %s%*.*s : %d\n", buf, "In use ", pad - 8, pad - 8, padding, proc_details.dir_entry->in_use);
80+
81+
snprintf(buf, BUF, "%s> %s%*.*s : %s\n", buf, "File Operations ", pad - 17, pad - 17, padding, proc_details.fops[0] ? "Yes" : "No");
82+
if(proc_details.fops[0]) {
83+
snprintf(buf, BUF, "%s %s = {\n", buf, proc_details.fops);
84+
SHOW_FUNCTION(open)
85+
SHOW_FUNCTION(read)
86+
SHOW_FUNCTION(write)
87+
SHOW_FUNCTION(release)
88+
SHOW_FUNCTION(llseek)
89+
snprintf(buf, BUF, "%s };\n", buf);
90+
}
91+
seq_puts(m, buf);
92+
return 0;
93+
}
94+
95+
96+
// ----------------------------------------------------------------------------------------------------------
97+
static int proc_procreadwrite_open (struct inode *inode, struct file *file) {
98+
return single_open (file, proc_procreadwrite_show, NULL);
99+
}
100+
39101

40102
// ----------------------------------------------------------------------------------------------------------
41-
static void get_owner(const char* fname) {
103+
static ssize_t proc_procreadwrite_write (struct file *file, const char * buf, size_t size, loff_t * ppos) {
104+
size_t len = 255;
105+
size_t i;
106+
107+
if (len > size) {
108+
len = size;
109+
}
110+
111+
if (copy_from_user (proc_details.filename, buf, len)) {
112+
return -EFAULT;
113+
}
114+
115+
proc_details.filename[len] = 0;
116+
for(i = 0; i < len; i++) {
117+
if(proc_details.filename[i] == '\r' || proc_details.filename[i] == '\n') {
118+
proc_details.filename[i] = 0;
119+
break;
120+
}
121+
}
122+
123+
printk(KERN_INFO MOD "checking module: %s\n", proc_details.filename);
124+
get_details();
125+
return len;
126+
}
127+
128+
129+
130+
// ----------------------------------------------------------------------------------------------------------
131+
static struct file_operations proc_procreadwrite_operations = {
132+
.open = proc_procreadwrite_open,
133+
.read = seq_read,
134+
.write = proc_procreadwrite_write,
135+
.llseek = seq_lseek,
136+
.release = single_release,
137+
};
138+
139+
140+
141+
// ----------------------------------------------------------------------------------------------------------
142+
#define GET_FUNCTION(fnc) if(proc_details.dir_entry->proc_fops->fnc) {\
143+
symbol_name((size_t)(proc_details.dir_entry->proc_fops->fnc), proc_details.fops_##fnc);\
144+
} else {\
145+
proc_details.fops_##fnc[0] = 0;\
146+
}
147+
148+
static void get_details() {
42149
int rv;
43150
unsigned int len;
44151
unsigned long symbolsize, offset;
45-
const char* fn = fname;
46-
char* modname = NULL, tmpstr;
152+
const char* fn = proc_details.filename;
153+
char *tmpstr, *modname = NULL;
47154
char namebuf[128];
48-
struct proc_dir_entry *de = NULL;
49155

50156
spin_lock(subdir_lock);
51-
rv = xlate(fname, &de, &fn);
157+
rv = xlate(proc_details.filename, &(proc_details.dir_entry), &fn);
52158
printk(KERN_INFO MOD "Ret: %d, Residual: %s\n", rv, fn);
53159
if(rv != 0) {
54160
spin_unlock(subdir_lock);
55161
return;
56162
}
57163
len = strlen(fn);
58-
de = subdir_find(de, fn, len);
59-
if(de) {
60-
printk(KERN_INFO MOD "Name: %s, proc fops: %p\n", de->name, de->proc_fops);
61-
tmpstr = syms_lookup((size_t)(de->proc_fops), &symbolsize, &offset, &modname, namebuf);
62-
printk(KERN_INFO MOD "Modname: %s\n", modname);
63-
symbol_name((size_t)(de->proc_fops), namebuf);
64-
printk(KERN_INFO MOD "Symbol: %s\n", namebuf);
164+
// find entry in procfs
165+
proc_details.dir_entry = subdir_find(proc_details.dir_entry, fn, len);
166+
if(proc_details.dir_entry) {
167+
printk(KERN_INFO MOD "Name: %s, proc fops: %p\n", proc_details.dir_entry->name, proc_details.dir_entry->proc_fops);
168+
// get module name
169+
tmpstr = syms_lookup((size_t)(proc_details.dir_entry->proc_fops), &symbolsize, &offset, &modname, namebuf);
170+
if(modname) {
171+
strlcpy(proc_details.modname, modname, 128);
172+
} else {
173+
strcpy(proc_details.modname, "N/A");
174+
}
175+
// get file operation struct name
176+
symbol_name((size_t)(proc_details.dir_entry->proc_fops), proc_details.fops);
177+
// check which functions are registered
178+
GET_FUNCTION(open)
179+
GET_FUNCTION(read)
180+
GET_FUNCTION(write)
181+
GET_FUNCTION(release)
182+
GET_FUNCTION(llseek)
65183
}
66184
spin_unlock(subdir_lock);
67-
68185
}
69186

70187

71-
// ----------------------------------------------------------------------------------------------------------
72-
static int proc_read(struct seq_file *m, void *v) {
73-
seq_printf(m, "test\n");
74-
get_owner("kallsyms");
75-
76-
return 0;
77-
}
78-
79-
// ----------------------------------------------------------------------------------------------------------
80-
static int pm_open(struct inode *i, struct file *f) {
81-
return single_open(f, proc_read, NULL);
82-
}
83-
84-
// ----------------------------------------------------------------------------------------------------------
85-
static const struct file_operations temp_proc_fops = {
86-
.owner = THIS_MODULE,
87-
.open = pm_open,
88-
.read = seq_read,
89-
.release = single_release,
90-
};
91-
92188
// ----------------------------------------------------------------------------------------------------------
93189
static int __init procowner_init(void)
94190
{
95-
printk(KERN_INFO MOD "module start\n");
96-
proc_create("procowner", 0, NULL, &temp_proc_fops);
97-
98-
xlate = kallsyms_lookup_name("__xlate_proc_name");
99-
if(!xlate) {
100-
printk(KERN_INFO MOD "__xlate_proc_name not found!\n");
101-
return -ENODEV;
102-
}
103-
subdir_lock = kallsyms_lookup_name("proc_subdir_lock");
104-
if(!subdir_lock) {
105-
printk(KERN_INFO MOD "proc_subdir_lock not found!\n");
106-
return -ENODEV;
107-
}
108-
subdir_find = kallsyms_lookup_name("pde_subdir_find");
109-
if(!subdir_find) {
110-
printk(KERN_INFO MOD "pde_subdir_find not found!\n");
111-
return -ENODEV;
112-
}
113-
syms_lookup = kallsyms_lookup_name("kallsyms_lookup");
114-
if(!syms_lookup) {
115-
printk(KERN_INFO MOD "kallsyms_lookup not found!\n");
116-
return -ENODEV;
117-
}
118-
symbol_name = kallsyms_lookup_name("lookup_symbol_name");
119-
if(!symbol_name) {
120-
printk(KERN_INFO MOD "lookup_symbol_name not found!\n");
121-
return -ENODEV;
122-
}
191+
printk(KERN_INFO MOD "module start\n");
192+
int merr = 0;
193+
194+
proc_create("procdetails", 0666, NULL, &proc_procreadwrite_operations);
123195

124-
return 0;
196+
xlate = kallsyms_lookup_name("__xlate_proc_name");
197+
if(!xlate) {
198+
printk(KERN_INFO MOD "__xlate_proc_name not found!\n");
199+
return -ENODEV;
200+
}
201+
subdir_lock = kallsyms_lookup_name("proc_subdir_lock");
202+
if(!subdir_lock) {
203+
printk(KERN_INFO MOD "proc_subdir_lock not found!\n");
204+
return -ENODEV;
205+
}
206+
subdir_find = kallsyms_lookup_name("pde_subdir_find");
207+
if(!subdir_find) {
208+
printk(KERN_INFO MOD "pde_subdir_find not found!\n");
209+
return -ENODEV;
210+
}
211+
syms_lookup = kallsyms_lookup_name("kallsyms_lookup");
212+
if(!syms_lookup) {
213+
printk(KERN_INFO MOD "kallsyms_lookup not found!\n");
214+
return -ENODEV;
215+
}
216+
symbol_name = kallsyms_lookup_name("lookup_symbol_name");
217+
if(!symbol_name) {
218+
printk(KERN_INFO MOD "lookup_symbol_name not found!\n");
219+
return -ENODEV;
220+
}
221+
222+
return 0;
125223
}
126224

127225
// ----------------------------------------------------------------------------------------------------------
128226
static void __exit procowner_exit(void)
129227
{
130-
remove_proc_entry("procowner", NULL);
228+
remove_proc_entry("procdetails", NULL);
131229

132-
printk(KERN_INFO MOD "module end\n");
230+
printk(KERN_INFO MOD "module end\n");
133231
}
134232

135233

0 commit comments

Comments
 (0)