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_BINARIES[] = "target_binaries";
22 static const char PRELOAD_BINARIES_LIST[] = "bins_list";
23 static const char PRELOAD_BINARIES_ADD[] = "bins_add";
24 static const char PRELOAD_BINARIES_REMOVE[] = "bins_remove";
25 static const char PRELOAD_CALLER[] = "caller";
26 static const char PRELOAD_HANDLERS_PATH[] = "handlers_path";
27 static const char PRELOAD_LINKER_DATA[] = "linker";
28 static const char PRELOAD_LINKER_PATH[] = "linker_path";
29 static const char PRELOAD_LINKER_R_DEBUG_OFFSET[] = "r_debug_offset";
34 struct dentry *dentry;
37 static struct dentry *preload_root;
38 static struct loader_info __loader_info;
40 static unsigned long r_debug_offset = 0;
41 static DEFINE_SPINLOCK(__dentry_lock);
43 static inline void dentry_lock(void)
45 spin_lock(&__dentry_lock);
48 static inline void dentry_unlock(void)
50 spin_unlock(&__dentry_lock);
54 static void set_loader_file(char *path)
56 __loader_info.path = path;
58 __loader_info.dentry = get_dentry(__loader_info.path);
62 struct dentry *preload_debugfs_get_loader_dentry(void)
64 struct dentry *dentry;
67 dentry = __loader_info.dentry;
73 unsigned long preload_debugfs_get_loader_offset(void)
75 /* TODO Think about sync */
76 return __loader_info.offset;
79 static void clean_loader_info(void)
81 if (__loader_info.path != NULL)
82 kfree(__loader_info.path);
83 __loader_info.path = NULL;
86 if (__loader_info.dentry != NULL)
87 put_dentry(__loader_info.dentry);
89 __loader_info.dentry = NULL;
90 __loader_info.offset = 0;
95 struct dentry *debugfs_create_ptr(const char *name, mode_t mode,
96 struct dentry *parent,
99 struct dentry *dentry;
101 #if BITS_PER_LONG == 32
102 dentry = debugfs_create_x32(name, mode, parent, (u32 *)value);
103 #elif BITS_PER_LONG == 64
104 dentry = debugfs_create_x64(name, mode, parent, (u64 *)value);
106 #error Unsupported BITS_PER_LONG value
113 /* ===========================================================================
115 * ===========================================================================
118 static ssize_t loader_path_write(struct file *file, const char __user *buf,
119 size_t len, loff_t *ppos)
124 if (preload_module_is_running())
129 path = kmalloc(len, GFP_KERNEL);
134 if (copy_from_user(path, buf, len)) {
139 path[len - 1] = '\0';
140 set_loader_file(path);
150 static const struct file_operations loader_path_file_ops = {
151 .owner = THIS_MODULE,
152 .write = loader_path_write,
156 /* ===========================================================================
158 * ===========================================================================
161 static ssize_t bin_add_write(struct file *file, const char __user *buf,
162 size_t len, loff_t *ppos)
167 path = kmalloc(len, GFP_KERNEL);
170 goto bin_add_write_out;
173 if (copy_from_user(path, buf, len)) {
175 goto bin_add_write_out;
178 path[len - 1] = '\0';
180 if (preload_control_add_instrumented_binary(path) != 0) {
181 printk(PRELOAD_PREFIX "Cannot add binary %s\n", path);
183 goto bin_add_write_out;
194 static ssize_t bin_remove_write(struct file *file, const char __user *buf,
195 size_t len, loff_t *ppos)
199 ret = preload_control_clean_instrumented_bins();
201 printk(PRELOAD_PREFIX "Error during clean!\n");
203 goto bin_remove_write_out;
208 bin_remove_write_out:
212 static ssize_t bin_list_read(struct file *file, char __user *usr_buf,
213 size_t count, loff_t *ppos)
216 unsigned int files_cnt = 0;
217 ssize_t len = 0, tmp, ret = 0;
218 char **filenames = NULL;
222 files_cnt = preload_control_get_bin_names(&filenames);
224 if (files_cnt == 0) {
225 printk(PRELOAD_PREFIX "Cannot read binaries names!\n");
227 goto bin_list_read_out;
230 for (i = 0; i < files_cnt; i++)
231 len += strlen(filenames[i]);
233 buf = kmalloc(len + files_cnt, GFP_KERNEL);
236 goto bin_list_read_fail;
241 for (i = 0; i < files_cnt; i++) {
242 tmp = strlen(filenames[i]);
243 memcpy(ptr, filenames[i], tmp);
249 preload_control_release_bin_names(&filenames);
251 return simple_read_from_buffer(usr_buf, count, ppos, buf, len);
254 preload_control_release_bin_names(&filenames);
260 static const struct file_operations bin_list_file_ops = {
261 .owner = THIS_MODULE,
262 .read = bin_list_read
265 static const struct file_operations bin_add_file_ops = {
266 .owner = THIS_MODULE,
267 .write = bin_add_write,
270 static const struct file_operations bin_remove_file_ops = {
271 .owner = THIS_MODULE,
272 .write = bin_remove_write,
276 /* ===========================================================================
278 * ===========================================================================
282 static ssize_t linker_path_write(struct file *file, const char __user *buf,
283 size_t len, loff_t *ppos)
288 path = kmalloc(len, GFP_KERNEL);
291 goto linker_path_write_out;
294 if (copy_from_user(path, buf, len)) {
296 goto linker_path_write_out;
299 path[len - 1] = '\0';
301 if (preload_storage_set_linker_info(path) != 0) {
302 printk(PRELOAD_PREFIX "Cannot set linker path %s\n", path);
304 goto linker_path_write_out;
309 linker_path_write_out:
315 static const struct file_operations linker_path_file_ops = {
316 .owner = THIS_MODULE,
317 .write = linker_path_write,
321 /* ===========================================================================
323 * ===========================================================================
327 static ssize_t handlers_path_write(struct file *file, const char __user *buf,
328 size_t len, loff_t *ppos)
333 path = kmalloc(len, GFP_KERNEL);
336 goto handlers_path_write_out;
339 if (copy_from_user(path, buf, len)) {
341 goto handlers_path_write_out;
344 path[len - 1] = '\0';
346 if (preload_storage_set_handlers_info(path) != 0) {
347 printk(PRELOAD_PREFIX "Cannot set handler path %s\n", path);
349 goto handlers_path_write_out;
354 handlers_path_write_out:
360 static const struct file_operations handlers_path_file_ops = {
361 .owner = THIS_MODULE,
362 .write = handlers_path_write,
368 unsigned long preload_debugfs_r_debug_offset(void)
370 return r_debug_offset;
373 int preload_debugfs_init(void)
375 struct dentry *swap_dentry, *root, *loader, *open_p, *lib_path,
376 *bin_path, *bin_list, *bin_add, *bin_remove,
377 *linker_dir, *linker_path, *linker_offset, *handlers_path;
381 if (!debugfs_initialized())
385 swap_dentry = swap_debugfs_getdir();
390 root = debugfs_create_dir(PRELOAD_FOLDER, swap_dentry);
391 if (IS_ERR_OR_NULL(root))
396 loader = debugfs_create_dir(PRELOAD_LOADER, root);
397 if (IS_ERR_OR_NULL(root)) {
402 open_p = debugfs_create_ptr(PRELOAD_LOADER_OFFSET, PRELOAD_DEFAULT_PERMS,
403 loader, &__loader_info.offset);
404 if (IS_ERR_OR_NULL(open_p)) {
409 lib_path = debugfs_create_file(PRELOAD_LOADER_PATH, PRELOAD_DEFAULT_PERMS,
410 loader, NULL, &loader_path_file_ops);
411 if (IS_ERR_OR_NULL(lib_path)) {
416 bin_path = debugfs_create_dir(PRELOAD_BINARIES, root);
417 if (IS_ERR_OR_NULL(bin_path)) {
422 bin_list = debugfs_create_file(PRELOAD_BINARIES_LIST, PRELOAD_DEFAULT_PERMS,
423 bin_path, NULL, &bin_list_file_ops);
424 if (IS_ERR_OR_NULL(bin_list)) {
429 bin_add = debugfs_create_file(PRELOAD_BINARIES_ADD, PRELOAD_DEFAULT_PERMS,
430 bin_path, NULL, &bin_add_file_ops);
431 if (IS_ERR_OR_NULL(bin_add)) {
436 bin_remove = debugfs_create_file(PRELOAD_BINARIES_REMOVE,
437 PRELOAD_DEFAULT_PERMS, bin_path, NULL,
438 &bin_remove_file_ops);
439 if (IS_ERR_OR_NULL(bin_remove)) {
444 linker_dir = debugfs_create_dir(PRELOAD_LINKER_DATA, root);
445 if (IS_ERR_OR_NULL(linker_dir)) {
450 linker_path = debugfs_create_file(PRELOAD_LINKER_PATH,
451 PRELOAD_DEFAULT_PERMS, linker_dir, NULL,
452 &linker_path_file_ops);
453 if (IS_ERR_OR_NULL(linker_path)) {
458 linker_offset = debugfs_create_ptr(PRELOAD_LINKER_R_DEBUG_OFFSET,
459 PRELOAD_DEFAULT_PERMS, linker_dir,
461 if (IS_ERR_OR_NULL(linker_offset)) {
466 handlers_path = debugfs_create_file(PRELOAD_HANDLERS_PATH,
467 PRELOAD_DEFAULT_PERMS, root, NULL,
468 &handlers_path_file_ops);
469 if (IS_ERR_OR_NULL(handlers_path)) {
478 debugfs_remove_recursive(root);
481 printk(PRELOAD_PREFIX "Debugfs initialization failure: %d\n", ret);
486 void preload_debugfs_exit(void)
489 debugfs_remove_recursive(preload_root);
492 preload_module_set_not_ready();