-
-
Save ninjamar/fbf236cc09d3a00460b880d0220054b3 to your computer and use it in GitHub Desktop.
Test Proc Device
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <linux/init.h> | |
#include <linux/module.h> | |
#include <linux/kernel.h> | |
#include <linux/syscalls.h> | |
#include <linux/proc_fs.h> | |
#include <linux/umh.h> | |
#include <linux/version.h> | |
MODULE_LICENSE("GPL"); | |
MODULE_AUTHOR("Xcellerator"); | |
MODULE_AUTHOR("ninjamar"); | |
MODULE_DESCRIPTION("Test Proc Device"); | |
MODULE_VERSION("0.01"); | |
struct proc_dir_entry *proc_file_entry_input; | |
struct proc_dir_entry *proc_file_entry_output; | |
char *argv[2]; | |
char *envp[3]; | |
char *input_output = NULL; | |
int input_output_len = 0; | |
int handle_cmd(void){ | |
int ret; | |
if(argv[0] == NULL) | |
return 0; | |
ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_EXEC); | |
return ret; | |
} | |
ssize_t input_write(struct file *file, const char *buf, size_t len, loff_t *offset){ | |
int ret; | |
char *kbuf = NULL; | |
long error; | |
char *suffix = " > /proc/output"; | |
kbuf = kzalloc(len, GFP_KERNEL); | |
error = copy_from_user(kbuf, buf, len-1); | |
if(error) | |
return -1; | |
argv[0] = "echo"; | |
argv[1] = kzalloc(len+16, GFP_KERNEL); | |
strncpy(argv[2], kbuf, len-1); | |
strcat(argv[2], suffix); | |
printk(KERN_DEBUG "Echoing to /proc/output"); | |
ret = handle_cmd(); | |
kfree(kbuf); | |
return len; | |
} | |
ssize_t output_write(struct file *file, const char *buf, size_t len, loff_t *offset){ | |
long error; | |
if(input_output_len != 0) | |
kfree(input_output); | |
input_output = kzalloc(len, GFP_KERNEL); | |
error = copy_from_user(input_output, buf, len); | |
if(error) | |
return -1; | |
input_output_len = len; | |
return len; | |
} | |
ssize_t output_read(struct file *file, char *buf, size_t len, loff_t *offset) | |
{ | |
int ret; | |
char *kbuf = NULL; | |
long error; | |
static int finished = 0; | |
kbuf = kzalloc(input_output_len, GFP_KERNEL); | |
strncpy(kbuf, input_output, input_output_len); | |
if ( finished ){ | |
finished = 0; | |
ret = 0; | |
goto out; | |
} | |
else { | |
finished = 1; | |
error = copy_to_user(buf, kbuf, input_output_len); | |
if(error) | |
return -1; | |
ret = input_output_len; | |
goto out; | |
} | |
out: | |
kfree(kbuf); | |
return ret; | |
} | |
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0) | |
static const struct proc_ops proc_file_fops_input = { | |
.proc_write = input_write, | |
}; | |
static const struct proc_ops proc_file_fops_output = { | |
.proc_write = output_write, | |
.proc_read = output_read, | |
}; | |
#else | |
static const struct file_operations proc_file_fops_input = { | |
.owner = THIS_MODULE, | |
.write = input_write, | |
}; | |
static const struct file_operations proc_file_fops_output = { | |
.owner = THIS_MODULE, | |
.read = output_read, | |
.write = output_write, | |
}; | |
#endif | |
static int __init escape_init(void){ | |
printk(KERN_INFO "input: loaded\n"); | |
printk(KERN_INFO "output: loaded\n"); | |
proc_file_entry_input = proc_create("input", 0666, NULL, &proc_file_fops_input); | |
proc_file_entry_output = proc_create("output", 0666, NULL, &proc_file_fops_output); | |
if( (proc_file_entry_input == NULL) || (proc_file_entry_output == NULL) ) | |
return -ENOMEM; | |
return 0; | |
} | |
static void __exit escape_exit(void){ | |
kfree(input_output); | |
remove_proc_entry("escape", NULL); | |
remove_proc_entry("output", NULL); | |
printk(KERN_INFO "input: unloaded\n"); | |
printk(KERN_INFO "output: unloaded\n"); | |
} | |
module_init(escape_init); | |
module_exit(escape_exit); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment