-
Notifications
You must be signed in to change notification settings - Fork 0
/
clouddev.c
121 lines (91 loc) · 3.31 KB
/
clouddev.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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**
Copyright (c) 2015 Maciej Nabozny
This file is part of KernelConnect project.
KernelConnect is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
KernelConnect is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with KernelConnect. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clouddev.h"
static ssize_t dev_read(struct file *filp, char __user *data, size_t size, loff_t *offset) {
struct message *msg;
msg = message_get_sent();
if (msg == NULL) {
return 0;
}
if (msg->size > size) {
printk(KERN_INFO "dev_read: not enough space to copy message (%lu). Message is %zu\n", size, msg->size);
return -EAGAIN;
}
copy_to_user(data, &msg->pid, sizeof(msg->pid));
copy_to_user(data+sizeof(msg->pid), msg->data, msg->size);
message_destroy(msg);
return msg->size;
}
static ssize_t dev_write(struct file *filp, const char __user *data, size_t size, loff_t *offset) {
struct message *msg;
void *msg_data;
printk(KERN_DEBUG "dev_write: write\n");
msg_data = kmalloc(size, GFP_KERNEL);
msg = message_new(msg_data, size);
printk(KERN_DEBUG "Message pid size: %lu\n", sizeof(msg->pid));
copy_from_user(&msg->pid, data, sizeof(msg->pid));
copy_from_user(&msg->data, data + sizeof(msg->pid), size - sizeof(msg->pid));
message_put_incoming(msg);
return size;
}
int dev_ioctl(struct file *filp, unsigned int func, unsigned long data) {
// TODO: Lock
struct pid *p;
struct task_struct *task;
if (func == CLOUDDEV_TRACE_ENABLE) {
printk(KERN_INFO "dev_ioctl: trace enable for pid %d\n", data);
p = find_get_pid(data);
task = get_pid_task(p, PIDTYPE_PID);
task->cloudover_flags = 0x01;
} else if (func == CLOUDDEV_TRACE_DISABLE) {
printk(KERN_INFO "dev_ioctl: trace enable for pid %d\n", data);
p = find_get_pid(data);
task = get_pid_task(p, PIDTYPE_PID);
task->cloudover_flags = 0x00;
} else {
printk(KERN_ALERT "dev_ioctl: unknown command %x\n", func);
}
// TODO: Unlock
return 0;
}
int dev_open(struct inode *inp, struct file *filp) {
printk(KERN_DEBUG "dev_open: device opened\n");
return 0;
}
int dev_release(struct inode *inp, struct file *filp) {
printk(KERN_DEBUG "dev_release: device closed\n");
return 0;
}
static struct file_operations fops = {
.open = dev_open,
.read = dev_read,
.write = dev_write,
.release = dev_release,
.unlocked_ioctl = dev_ioctl,
};
int device_init(void) {
int dev;
dev = register_chrdev(109, "kernelconect", &fops);
if (dev >= 0) {
printk(KERN_INFO "device_init: registered kernelConnect device with major %d\n", dev);
return 0;
} else {
printk(KERN_CRIT "device_init: failed to register kernelConnect device: %d\n", dev);
return -1;
}
}
void device_cleanup(void) {
unregister_chrdev(109, "kernelconnect");
}