ioctl support copy_to_user_variant_buffer
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
#include <linux/cdev.h> // for cdev
|
||||
#include "monitor_kernel.h"
|
||||
|
||||
#include <linux/cdev.h> // for cdev
|
||||
#include <linux/device.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h> // for kmalloc
|
||||
|
||||
#include "monitor_kernel.h"
|
||||
#include <linux/slab.h> // for kmalloc
|
||||
|
||||
#define DEVICE_NAME "variable_monitor"
|
||||
|
||||
@@ -21,11 +21,11 @@ struct my_device_data {
|
||||
|
||||
static int device_open(struct inode *inode, struct file *file) {
|
||||
struct my_device_data *data;
|
||||
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__, current->pid);
|
||||
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__,
|
||||
current->pid);
|
||||
// save pid
|
||||
data = kmalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
if (!data) return -ENOMEM;
|
||||
data->pid = current->pid;
|
||||
file->private_data = data;
|
||||
return 0;
|
||||
@@ -34,26 +34,49 @@ static int device_open(struct inode *inode, struct file *file) {
|
||||
static int device_release(struct inode *inode, struct file *file) {
|
||||
// load pid
|
||||
struct my_device_data *data = file->private_data;
|
||||
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__, data->pid);
|
||||
printk(KERN_INFO "variable_monitor fun: %s with pid %d\n", __FUNCTION__,
|
||||
data->pid);
|
||||
// clear watch with pid
|
||||
clear_watch(data->pid);
|
||||
kfree(data); // free data memory
|
||||
kfree(data); // free data memory
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long device_ioctl(struct file *file, unsigned int ioctl_num,
|
||||
unsigned long ioctl_param) {
|
||||
int ret = 0;
|
||||
watch_arg warg;
|
||||
// copy watch_arg
|
||||
if (copy_from_user(&warg, (watch_arg *)ioctl_param, sizeof(warg))) {
|
||||
return -EACCES;
|
||||
ioctl_dump_param dump_param;
|
||||
|
||||
switch (ioctl_num) {
|
||||
case 0:
|
||||
// copy watch_arg
|
||||
if (copy_from_user(&warg, (watch_arg *)ioctl_param, sizeof(warg))) {
|
||||
return -EACCES;
|
||||
}
|
||||
printk(KERN_INFO
|
||||
"Watch_arg: task_id=%d, name=%s, ptr=%p, length_byte=%d, "
|
||||
"time_ns=%ld, threshold=%lld\n",
|
||||
warg.task_id, warg.name, warg.ptr, warg.length_byte, warg.time_ns,
|
||||
warg.threshold);
|
||||
// start watch variable
|
||||
start_watch_variable(warg);
|
||||
break;
|
||||
case 1:
|
||||
ret = copy_from_user(&dump_param, (void *)ioctl_param,
|
||||
sizeof(ioctl_dump_param));
|
||||
if (!ret) {
|
||||
ret = copy_to_user_variant_buffer(
|
||||
&load_monitor_variant_buffer, dump_param.user_ptr_len,
|
||||
dump_param.user_buf, dump_param.user_buf_len);
|
||||
}
|
||||
printk(KERN_INFO "copy_to_user \n");
|
||||
|
||||
/* code */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
printk(KERN_INFO "Watch_arg: task_id=%d, name=%s, ptr=%p, length_byte=%d, "
|
||||
"time_ns=%ld, threshold=%lld\n",
|
||||
warg.task_id, warg.name, warg.ptr, warg.length_byte, warg.time_ns,
|
||||
warg.threshold);
|
||||
// start watch variable
|
||||
start_watch_variable(warg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
// for memory access
|
||||
// #include <linux/sched.h>
|
||||
|
||||
typedef struct {
|
||||
int __user *user_ptr_len;
|
||||
size_t __user user_buf_len;
|
||||
void __user *user_buf;
|
||||
} ioctl_dump_param;
|
||||
|
||||
typedef struct {
|
||||
pid_t task_id; // current process id
|
||||
struct page *page;
|
||||
|
||||
@@ -19,7 +19,7 @@ int start_watch(watch_arg w_arg) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ioctl(file_desc, 1, &w_arg) < 0) {
|
||||
if (ioctl(file_desc, 0, &w_arg) < 0) {
|
||||
printf("ioctl failed\n");
|
||||
close(file_desc);
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user