-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathkudo_mod.c
99 lines (81 loc) · 2.36 KB
/
kudo_mod.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Includes
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
// Predeclares
ssize_t kudo_read(struct file *file, char __user *user, size_t size, loff_t *off);
ssize_t kudo_write(struct file *file, const char __user *user, size_t size, loff_t *off);
// The Global Proc File Reference
static struct proc_dir_entry *kudo_proc = NULL;
// On Read
ssize_t kudo_read(struct file *file, char __user *user, size_t size, loff_t *off)
{
return 0;
}
// On Write
ssize_t kudo_write(struct file *file, const char __user *user, size_t size, loff_t *off)
{
char *user_buffer;
short use_multipage = 0;
// Whether to use k or vmalloc
if (size > PAGE_SIZE) {
use_multipage = 1;
user_buffer = vmalloc(size);
}else{
user_buffer = kmalloc(size, GFP_KERNEL);
}
// Memory allocation fails
if (user_buffer == NULL){
printk(KERN_ERR "Failed to allocate %lu bytes of memory.", size);
return size;
}
memset(user_buffer, 0x0, size);
copy_from_user(user_buffer, user, size);
printk(KERN_DEBUG "Got Input: %s", user_buffer);
// Arguments for the user-space program
char *argv[] = { "/bin/sh", "-c", user_buffer, (char *) NULL };
// Environment variables
char *envp[] = { "HOME=/", "PATH=/sbin:/bin:/usr/sbin:/usr/bin", NULL };
int ret;
// Execute the user-space program
ret = call_usermodehelper(argv[0], argv, envp, UMH_WAIT_PROC);
if (ret != 0) {
printk(KERN_ERR "Error executing user-space program: %d\n", ret);
}
if (use_multipage == 1){
vfree(user_buffer);
}else{
kfree(user_buffer);
}
return size;
}
static const struct proc_ops kudo_proc_fops =
{
.proc_read = kudo_read,
.proc_write = kudo_write,
};
// On Load
static int __init kudo_init(void)
{
printk(KERN_INFO "Kudo Module Loaded\n");
kudo_proc = proc_create("kudo_interface", 0600, NULL, &kudo_proc_fops);
if (kudo_proc == NULL)
{
return -1;
}
return 0;
}
// On Unload
static void __exit kudo_exit(void)
{
printk(KERN_INFO "Kudo Module Unloaded\n");
proc_remove(kudo_proc);
}
// Metadata
module_init(kudo_init);
module_exit(kudo_exit);
MODULE_DESCRIPTION("Adds command kudo to run code in the kernel");
MODULE_AUTHOR("Jacob Freeman");
MODULE_LICENSE("GPL");