static const char GT_HANDLER[] = "handler";
static const char GT_HANDLER_FIXUP_OFF[] = "fixup_handler_off";
static const char GT_HANDLER_RELOC_OFF[] = "reloc_handler_off";
+static const char GT_PROC_FEATURES_OFF[] = "proc_features_off";
static const char GT_PTHREAD[] = "pthread";
static const char GT_MINIMAL_INIT[] = "minimal_init_off";
return get_ul_and_call(buf, len, gtm_set_handler_reloc_off);
}
+static ssize_t proc_features_off_write(struct file *file,
+ const char __user *buf, size_t len,
+ loff_t *ppos)
+{
+ return get_ul_and_call(buf, len, gtm_set_proc_features_off);
+}
+
static const struct file_operations handler_path_fops = {
.owner = THIS_MODULE,
.write = handler_path_write,
.write = handler_reloc_off_write,
};
+static const struct file_operations proc_features_off_fops = {
+ .owner = THIS_MODULE,
+ .write = proc_features_off_write,
+};
+
/* ===========================================================================
* = TARGETS =
* ===========================================================================
goto remove;
}
+ dentry = swap_debugfs_create_file(GT_PROC_FEATURES_OFF,
+ GT_DEFAULT_PERMS, handler, NULL,
+ &proc_features_off_fops);
+ if (IS_ERR_OR_NULL(dentry)) {
+ ret = -ENOMEM;
+ goto remove;
+ }
+
pthread = swap_debugfs_create_dir(GT_PTHREAD, root);
if (IS_ERR_OR_NULL(pthread)) {
ret = -ENOMEM;
static struct bin_data_t _linker_reloc;
static struct bin_data_t _handler_fixup;
static struct bin_data_t _handler_reloc;
+static struct bin_data_t _proc_features;
static struct bin_data_t _pthread_init;
static inline bool _is_handler_data_available(void)
{
return _is_bin_data_available(&_handler_fixup) &&
- _is_bin_data_available(&_handler_reloc);
+ _is_bin_data_available(&_handler_reloc) &&
+ _is_bin_data_available(&_proc_features);
}
static inline bool _is_pthread_data_available(void)
vaddr = base + off;
loader_module_prepare_ujump(ri, regs, vaddr);
- _set_in_handler(true);
return vaddr;
}
return _redirect_to_handler(ri, regs, hd, _handler_reloc.off);
}
+static unsigned long _redirect_to_proc_features(struct uretprobe_instance *ri,
+ struct pt_regs *regs,
+ struct hd_t *hd)
+{
+ return _redirect_to_handler(ri, regs, hd, _proc_features.off);
+}
+
static int _process_eh(struct uretprobe_instance *ri, struct pt_regs *regs,
goto out_set_orig;
if ((lpd_get_state(hd) == NOT_LOADED || lpd_get_state(hd) == FAILED) &&
- lpd_get_init_state(pd))
+ lpd_get_init_state(pd)) {
vaddr = loader_not_loaded_entry(ri, regs, pd, hd);
- else if (lpd_get_state(hd) == LOADED)
+ } else if (lpd_get_state(hd) == LOADED) {
+ _set_in_handler(true);
vaddr = rh(ri, regs, hd);
+ }
out_set_orig:
loader_set_priv_origin(ri, vaddr);
break;
case LOADING:
loader_loading_ret(ri, regs, pd, hd);
- rh(ri, regs, hd); /* TODO Think about: Possible only if we
- * do not need _set_in_handler() */
+ /* Patch all binaries */
+ if (lpd_get_state(hd))
+ rh(ri, regs, hd);
break;
case LOADED:
/* TODO Check does we need this if library is loaded
return 0;
}
-static int dl_fixup_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
+static int common_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
{
- return _process_rh(ri, regs, &_redirect_to_fixup_handler,
- _handler_fixup.dentry);
+ return _process_rh(ri, regs, &_redirect_to_proc_features,
+ _proc_features.dentry);
}
/* TODO Make ordinary interface. Now real data_size is set in init, because
* it is unknown in this module during compile time. */
-static struct probe_desc pin_fixup = MAKE_URPROBE(dl_fixup_eh, dl_fixup_rh, 0);
+static struct probe_desc pin_fixup = MAKE_URPROBE(dl_fixup_eh, common_rh, 0);
static int dl_reloc_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
_handler_reloc.dentry);
}
-static int dl_reloc_rh(struct uretprobe_instance *ri, struct pt_regs *regs)
-{
- return _process_rh(ri, regs, &_redirect_to_reloc_handler,
- _handler_reloc.dentry);
-}
-
/* TODO Make ordinary interface. Now real data_size is set in init, because
* it is unknown in this module during compile time. */
-static struct probe_desc pin_reloc = MAKE_URPROBE(dl_reloc_eh, dl_reloc_rh, 0);
+static struct probe_desc pin_reloc = MAKE_URPROBE(dl_reloc_eh, common_rh, 0);
static int pthread_init_eh(struct uretprobe_instance *ri, struct pt_regs *regs)
if (dentry == NULL)
return -EINVAL;
- if (_handler_fixup.dentry != NULL ||
- _handler_reloc.dentry != NULL) {
- if (_handler_fixup.dentry != NULL)
- swap_put_dentry(_handler_fixup.dentry);
- else
- swap_put_dentry(_handler_reloc.dentry);
- }
+ if (_handler_fixup.dentry)
+ swap_put_dentry(_handler_fixup.dentry);
+
+ if (_handler_reloc.dentry)
+ swap_put_dentry(_handler_reloc.dentry);
+
+ if (_proc_features.dentry)
+ swap_put_dentry(_proc_features.dentry);
_handler_fixup.dentry = dentry;
_handler_reloc.dentry = dentry;
+ _proc_features.dentry = dentry;
/* TODO Do smth with this:
* make interface for loader to remove handlers
return 0;
}
+int gtm_set_proc_features_off(unsigned long offset)
+{
+ _proc_features.off = offset;
+
+ return 0;
+}
+
int gtm_set_pthread_path(char *path)
{
struct dentry *dentry;