1 #include <linux/kernel.h>
2 #include <linux/debugfs.h>
5 #include <linux/module.h>
6 #include <linux/slab.h>
7 #include <linux/spinlock.h>
8 #include <linux/limits.h>
9 #include <asm/uaccess.h>
10 #include <master/swap_debugfs.h>
12 #include "preload_debugfs.h"
13 #include "preload_module.h"
14 #include "preload_control.h"
15 #include "preload_storage.h"
17 static const char PRELOAD_FOLDER[] = "preload";
18 static const char PRELOAD_LOADER[] = "loader";
19 static const char PRELOAD_LOADER_OFFSET[] = "loader_offset";
20 static const char PRELOAD_LOADER_PATH[] = "loader_path";
21 static const char PRELOAD_TARGET[] = "target_binaries";
22 static const char PRELOAD_IGNORED[] = "ignored_binaries";
23 static const char PRELOAD_BINARIES_LIST[] = "bins_list";
24 static const char PRELOAD_BINARIES_ADD[] = "bins_add";
25 static const char PRELOAD_BINARIES_REMOVE[] = "bins_remove";
26 static const char PRELOAD_CALLER[] = "caller";
27 static const char PRELOAD_HANDLERS_PATH[] = "handlers_path";
28 static const char PRELOAD_LINKER_DATA[] = "linker";
29 static const char PRELOAD_LINKER_PATH[] = "linker_path";
30 static const char PRELOAD_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset";
35 struct dentry *dentry;
38 static struct dentry *preload_root;
39 static struct loader_info __loader_info;
42 static struct dentry *target_list = NULL;
43 static struct dentry *target_add = NULL;
44 static struct dentry *target_remove = NULL;
45 static struct dentry *ignored_list = NULL;
46 static struct dentry *ignored_add = NULL;
47 static struct dentry *ignored_remove = NULL;
49 static unsigned long r_debug_offset = 0;
50 static DEFINE_SPINLOCK(__dentry_lock);
52 static inline void dentry_lock(void)
54 spin_lock(&__dentry_lock);
57 static inline void dentry_unlock(void)
59 spin_unlock(&__dentry_lock);
63 static void set_loader_file(char *path)
65 __loader_info.path = path;
67 __loader_info.dentry = get_dentry(__loader_info.path);
71 struct dentry *preload_debugfs_get_loader_dentry(void)
73 struct dentry *dentry;
76 dentry = __loader_info.dentry;
82 unsigned long preload_debugfs_get_loader_offset(void)
84 /* TODO Think about sync */
85 return __loader_info.offset;
88 static void clean_loader_info(void)
90 if (__loader_info.path != NULL)
91 kfree(__loader_info.path);
92 __loader_info.path = NULL;
95 if (__loader_info.dentry != NULL)
96 put_dentry(__loader_info.dentry);
98 __loader_info.dentry = NULL;
99 __loader_info.offset = 0;
104 struct dentry *debugfs_create_ptr(const char *name, mode_t mode,
105 struct dentry *parent,
106 unsigned long *value)
108 struct dentry *dentry;
110 #if BITS_PER_LONG == 32
111 dentry = debugfs_create_x32(name, mode, parent, (u32 *)value);
112 #elif BITS_PER_LONG == 64
113 dentry = debugfs_create_x64(name, mode, parent, (u64 *)value);
115 #error Unsupported BITS_PER_LONG value
122 /* ===========================================================================
124 * ===========================================================================
127 static ssize_t loader_path_write(struct file *file, const char __user *buf,
128 size_t len, loff_t *ppos)
133 if (preload_module_is_running())
138 path = kmalloc(len, GFP_KERNEL);
143 if (copy_from_user(path, buf, len)) {
148 path[len - 1] = '\0';
149 set_loader_file(path);
159 static const struct file_operations loader_path_file_ops = {
160 .owner = THIS_MODULE,
161 .write = loader_path_write,
165 /* ===========================================================================
167 * ===========================================================================
170 static ssize_t bin_add_write(struct file *file, const char __user *buf,
171 size_t len, loff_t *ppos)
176 path = kmalloc(len, GFP_KERNEL);
179 goto bin_add_write_out;
182 if (copy_from_user(path, buf, len)) {
184 goto bin_add_write_out;
187 path[len - 1] = '\0';
189 if (file->f_path.dentry == target_add)
190 ret = preload_control_add_instrumented_binary(path);
191 else if (file->f_path.dentry == ignored_add)
192 ret = preload_control_add_ignored_binary(path);
194 /* Should never occur */
195 printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
196 file->f_path.dentry->d_name.name);
198 goto bin_add_write_out;
203 printk(PRELOAD_PREFIX "Cannot add binary %s\n", path);
205 goto bin_add_write_out;
216 static ssize_t bin_remove_write(struct file *file, const char __user *buf,
217 size_t len, loff_t *ppos)
221 if (file->f_path.dentry == target_remove)
222 ret = preload_control_clean_instrumented_bins();
223 else if (file->f_path.dentry == ignored_remove)
224 ret = preload_control_clean_ignored_bins();
226 /* Should never occur */
227 printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
228 file->f_path.dentry->d_name.name);
230 goto bin_remove_write_out;
234 printk(PRELOAD_PREFIX "Error during clean!\n");
236 goto bin_remove_write_out;
241 bin_remove_write_out:
245 static ssize_t bin_list_read(struct file *file, char __user *usr_buf,
246 size_t count, loff_t *ppos)
249 unsigned int files_cnt = 0;
250 ssize_t len = 0, tmp, ret = 0;
251 char **filenames = NULL;
255 if (file->f_path.dentry == target_list) {
256 files_cnt = preload_control_get_target_names(&filenames);
257 } else if (file->f_path.dentry == ignored_list) {
258 files_cnt = preload_control_get_ignored_names(&filenames);
260 /* Should never occur */
261 printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
262 file->f_path.dentry->d_name.name);
264 goto bin_list_read_out;
267 if (files_cnt == 0) {
268 printk(PRELOAD_PREFIX "Cannot read binaries names!\n");
270 goto bin_list_read_fail;
273 for (i = 0; i < files_cnt; i++)
274 len += strlen(filenames[i]);
276 buf = kmalloc(len + files_cnt, GFP_KERNEL);
279 goto bin_list_read_fail;
284 for (i = 0; i < files_cnt; i++) {
285 tmp = strlen(filenames[i]);
286 memcpy(ptr, filenames[i], tmp);
292 ret = simple_read_from_buffer(usr_buf, count, ppos, buf, len);
297 if (file->f_path.dentry == target_list) {
298 preload_control_release_target_names(&filenames);
299 } else if (file->f_path.dentry == ignored_list) {
300 preload_control_release_ignored_names(&filenames);
302 /* Should never occur */
303 printk(PRELOAD_PREFIX "%s() called for invalid file %s!\n", __func__,
304 file->f_path.dentry->d_name.name);
312 static const struct file_operations bin_list_file_ops = {
313 .owner = THIS_MODULE,
314 .read = bin_list_read
317 static const struct file_operations bin_add_file_ops = {
318 .owner = THIS_MODULE,
319 .write = bin_add_write,
322 static const struct file_operations bin_remove_file_ops = {
323 .owner = THIS_MODULE,
324 .write = bin_remove_write,
328 /* ===========================================================================
330 * ===========================================================================
334 static ssize_t linker_path_write(struct file *file, const char __user *buf,
335 size_t len, loff_t *ppos)
340 path = kmalloc(len, GFP_KERNEL);
343 goto linker_path_write_out;
346 if (copy_from_user(path, buf, len)) {
348 goto linker_path_write_out;
351 path[len - 1] = '\0';
353 if (preload_storage_set_linker_info(path) != 0) {
354 printk(PRELOAD_PREFIX "Cannot set linker path %s\n", path);
356 goto linker_path_write_out;
361 linker_path_write_out:
367 static const struct file_operations linker_path_file_ops = {
368 .owner = THIS_MODULE,
369 .write = linker_path_write,
373 /* ===========================================================================
375 * ===========================================================================
379 static ssize_t handlers_path_write(struct file *file, const char __user *buf,
380 size_t len, loff_t *ppos)
385 path = kmalloc(len, GFP_KERNEL);
388 goto handlers_path_write_out;
391 if (copy_from_user(path, buf, len)) {
393 goto handlers_path_write_out;
396 path[len - 1] = '\0';
398 if (preload_storage_set_handlers_info(path) != 0) {
399 printk(PRELOAD_PREFIX "Cannot set handler path %s\n", path);
401 goto handlers_path_write_out;
406 handlers_path_write_out:
412 static const struct file_operations handlers_path_file_ops = {
413 .owner = THIS_MODULE,
414 .write = handlers_path_write,
420 unsigned long preload_debugfs_r_debug_offset(void)
422 return r_debug_offset;
425 int preload_debugfs_init(void)
427 struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path,
428 *target_path, *ignored_path, *linker_dir, *linker_path,
429 *linker_offset, *handlers_path;
433 if (!debugfs_initialized())
437 swap_dentry = swap_debugfs_getdir();
442 root = debugfs_create_dir(PRELOAD_FOLDER, swap_dentry);
443 if (IS_ERR_OR_NULL(root))
448 loader = debugfs_create_dir(PRELOAD_LOADER, root);
449 if (IS_ERR_OR_NULL(root)) {
454 open_p = debugfs_create_ptr(PRELOAD_LOADER_OFFSET, PRELOAD_DEFAULT_PERMS,
455 loader, &__loader_info.offset);
456 if (IS_ERR_OR_NULL(open_p)) {
461 lib_path = debugfs_create_file(PRELOAD_LOADER_PATH, PRELOAD_DEFAULT_PERMS,
462 loader, NULL, &loader_path_file_ops);
463 if (IS_ERR_OR_NULL(lib_path)) {
468 target_path = debugfs_create_dir(PRELOAD_TARGET, root);
469 if (IS_ERR_OR_NULL(target_path)) {
474 target_list = debugfs_create_file(PRELOAD_BINARIES_LIST,
475 PRELOAD_DEFAULT_PERMS, target_path, NULL,
477 if (IS_ERR_OR_NULL(target_list)) {
482 target_add = debugfs_create_file(PRELOAD_BINARIES_ADD,
483 PRELOAD_DEFAULT_PERMS, target_path, NULL,
485 if (IS_ERR_OR_NULL(target_add)) {
490 target_remove = debugfs_create_file(PRELOAD_BINARIES_REMOVE,
491 PRELOAD_DEFAULT_PERMS, target_path,
492 NULL, &bin_remove_file_ops);
493 if (IS_ERR_OR_NULL(target_remove)) {
498 ignored_path = debugfs_create_dir(PRELOAD_IGNORED, root);
499 if (IS_ERR_OR_NULL(ignored_path)) {
504 ignored_list = debugfs_create_file(PRELOAD_BINARIES_LIST,
505 PRELOAD_DEFAULT_PERMS, ignored_path,
506 NULL, &bin_list_file_ops);
507 if (IS_ERR_OR_NULL(ignored_list)) {
512 ignored_add = debugfs_create_file(PRELOAD_BINARIES_ADD,
513 PRELOAD_DEFAULT_PERMS, ignored_path, NULL,
515 if (IS_ERR_OR_NULL(ignored_add)) {
520 ignored_remove = debugfs_create_file(PRELOAD_BINARIES_REMOVE,
521 PRELOAD_DEFAULT_PERMS, ignored_path, NULL,
522 &bin_remove_file_ops);
523 if (IS_ERR_OR_NULL(ignored_remove)) {
528 linker_dir = debugfs_create_dir(PRELOAD_LINKER_DATA, root);
529 if (IS_ERR_OR_NULL(linker_dir)) {
534 linker_path = debugfs_create_file(PRELOAD_LINKER_PATH,
535 PRELOAD_DEFAULT_PERMS, linker_dir, NULL,
536 &linker_path_file_ops);
537 if (IS_ERR_OR_NULL(linker_path)) {
542 linker_offset = debugfs_create_ptr(PRELOAD_LINKER_R_DEBUG_OFFSET,
543 PRELOAD_DEFAULT_PERMS, linker_dir,
545 if (IS_ERR_OR_NULL(linker_offset)) {
550 handlers_path = debugfs_create_file(PRELOAD_HANDLERS_PATH,
551 PRELOAD_DEFAULT_PERMS, root, NULL,
552 &handlers_path_file_ops);
553 if (IS_ERR_OR_NULL(handlers_path)) {
562 debugfs_remove_recursive(root);
565 printk(PRELOAD_PREFIX "Debugfs initialization failure: %d\n", ret);
570 void preload_debugfs_exit(void)
573 debugfs_remove_recursive(preload_root);
576 target_remove = NULL;
579 ignored_remove = NULL;
582 preload_module_set_not_ready();