From a81037baec8f6d51000ca5ad6555936aa4804824 Mon Sep 17 00:00:00 2001 From: Hui Chen Date: Fri, 9 Feb 2018 13:25:47 -0500 Subject: [PATCH 1/3] resolved a compilation error in gcc-6 and a GPL issue --- 4.14.8/examples/chardev.c | 2 ++ 4.14.8/examples/chardev2.c | 2 ++ 4.14.8/examples/syscall.c | 25 ++++++++++++++----------- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/4.14.8/examples/chardev.c b/4.14.8/examples/chardev.c index 36580c4..98bfd87 100644 --- a/4.14.8/examples/chardev.c +++ b/4.14.8/examples/chardev.c @@ -16,6 +16,8 @@ #include #include +MODULE_LICENSE("GPL"); + /* * Prototypes - this would normally go in a .h file */ diff --git a/4.14.8/examples/chardev2.c b/4.14.8/examples/chardev2.c index 55917e4..cc5bff9 100644 --- a/4.14.8/examples/chardev2.c +++ b/4.14.8/examples/chardev2.c @@ -15,6 +15,8 @@ #include #include +MODULE_LICENSE("GPL"); + #include "chardev.h" #define SUCCESS 0 #define DEVICE_NAME "char_dev" diff --git a/4.14.8/examples/syscall.c b/4.14.8/examples/syscall.c index 16222c5..ccb901c 100644 --- a/4.14.8/examples/syscall.c +++ b/4.14.8/examples/syscall.c @@ -25,7 +25,7 @@ #include #include -unsigned long **sys_call_table; +sys_call_ptr_t *sys_call_table_ptr; unsigned long original_cr0; /* @@ -87,15 +87,18 @@ asmlinkage int our_sys_open(const char *filename, int flags, int mode) return original_call(filename, flags, mode); } -static unsigned long **aquire_sys_call_table(void) +static sys_call_ptr_t *aquire_sys_call_table(void) { unsigned long int offset = PAGE_OFFSET; - unsigned long **sct; + /* unsigned long **sct; */ + sys_call_ptr_t *sct; while (offset < ULLONG_MAX) { - sct = (unsigned long **)offset; + /* sct = (unsigned long **)offset; */ + sct = (sys_call_ptr_t *)offset; - if (sct[__NR_close] == (unsigned long *) sys_close) + /* if (sct[__NR_close] == (unsigned long *) sys_close) */ + if (sct[__NR_close] == (sys_call_ptr_t) sys_close) return sct; offset += sizeof(void *); @@ -106,7 +109,7 @@ static unsigned long **aquire_sys_call_table(void) static int __init syscall_start(void) { - if(!(sys_call_table = aquire_sys_call_table())) + if(!(sys_call_table_ptr = aquire_sys_call_table())) return -1; original_cr0 = read_cr0(); @@ -114,10 +117,10 @@ static int __init syscall_start(void) write_cr0(original_cr0 & ~0x00010000); /* keep track of the original open function */ - original_call = (void*)sys_call_table[__NR_open]; + original_call = (void*)sys_call_table_ptr[__NR_open]; /* use our open function instead */ - sys_call_table[__NR_open] = (unsigned long *)our_sys_open; + sys_call_table_ptr[__NR_open] = (sys_call_ptr_t)our_sys_open; write_cr0(original_cr0); @@ -128,14 +131,14 @@ static int __init syscall_start(void) static void __exit syscall_end(void) { - if(!sys_call_table) { + if(!sys_call_table_ptr) { return; } /* * Return the system call back to normal */ - if (sys_call_table[__NR_open] != (unsigned long *)our_sys_open) { + if (sys_call_table_ptr[__NR_open] != (sys_call_ptr_t) our_sys_open) { pr_alert("Somebody else also played with the "); pr_alert("open system call\n"); pr_alert("The system may be left in "); @@ -143,7 +146,7 @@ static void __exit syscall_end(void) } write_cr0(original_cr0 & ~0x00010000); - sys_call_table[__NR_open] = (unsigned long *)original_call; + sys_call_table_ptr[__NR_open] = (sys_call_ptr_t)original_call; write_cr0(original_cr0); msleep(2000); From a71f239a8f5102b1c11b8651b5495ec5f55cfb40 Mon Sep 17 00:00:00 2001 From: CISC7310X Date: Fri, 9 Feb 2018 19:03:47 -0500 Subject: [PATCH 2/3] revised syscall --- older_versions/4.9.11/examples/ioctl.c | 206 +++++++++++++++++++++++ older_versions/4.9.11/examples/syscall.c | 20 +-- 2 files changed, 216 insertions(+), 10 deletions(-) create mode 100644 older_versions/4.9.11/examples/ioctl.c diff --git a/older_versions/4.9.11/examples/ioctl.c b/older_versions/4.9.11/examples/ioctl.c new file mode 100644 index 0000000..b23762c --- /dev/null +++ b/older_versions/4.9.11/examples/ioctl.c @@ -0,0 +1,206 @@ +/*****************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +struct ioctl_arg { + unsigned int reg; + unsigned int val; +}; + +/* Documentation/ioctl/ioctl-number.txt */ +#define IOC_MAGIC '\x66' + +#define IOCTL_VALSET _IOW(IOC_MAGIC, 0, struct ioctl_arg) +#define IOCTL_VALGET _IOR(IOC_MAGIC, 1, struct ioctl_arg) +#define IOCTL_VALGET_NUM _IOR(IOC_MAGIC, 2, int) +#define IOCTL_VALSET_NUM _IOW(IOC_MAGIC, 3, int) + +#define IOCTL_VAL_MAXNR 3 +#define DRIVER_NAME "ioctltest" + +static unsigned int test_ioctl_major = 0; +static unsigned int num_of_dev = 1; +static struct cdev test_ioctl_cdev; +static int ioctl_num = 0; + +struct test_ioctl_data { + unsigned char val; + rwlock_t lock; +}; + +static long test_ioctl_ioctl(struct file* filp, unsigned int cmd, unsigned long arg) { + struct test_ioctl_data* ioctl_data = filp->private_data; + int retval = 0; + unsigned char val; + struct ioctl_arg data; + memset(&data, 0, sizeof(data)); + + switch (cmd) { + case IOCTL_VALSET: + + /* + if (!capable(CAP_SYS_ADMIN)) { + retval = -EPERM; + goto done; + } + if (!access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd))) { + retval = -EFAULT; + goto done; + } + */ + if (copy_from_user(&data, (int __user*)arg, sizeof(data))) { + retval = -EFAULT; + goto done; + } + + pr_alert("IOCTL set val:%x .\n", data.val); + write_lock(&ioctl_data->lock); + ioctl_data->val = data.val; + write_unlock(&ioctl_data->lock); + break; + + case IOCTL_VALGET: + /* + if (!access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd))) { + retval = -EFAULT; + goto done; + } + */ + read_lock(&ioctl_data->lock); + val = ioctl_data->val; + read_unlock(&ioctl_data->lock); + data.val = val; + + if (copy_to_user((int __user*)arg, &data, sizeof(data))) { + retval = -EFAULT; + goto done; + } + + break; + + case IOCTL_VALGET_NUM: + retval = __put_user(ioctl_num, (int __user*)arg); + break; + + case IOCTL_VALSET_NUM: + /* + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + */ + ioctl_num = arg; + break; + + default: + retval = -ENOTTY; + } + +done: + return retval; +} + +ssize_t test_ioctl_read(struct file* filp, char __user* buf, size_t count, loff_t* f_pos) { + struct test_ioctl_data* ioctl_data = filp->private_data; + unsigned char val; + int retval; + int i = 0; + read_lock(&ioctl_data->lock); + val = ioctl_data->val; + read_unlock(&ioctl_data->lock); + + for (; i < count ; i++) { + if (copy_to_user(&buf[i], &val, 1)) { + retval = -EFAULT; + goto out; + } + } + + retval = count; +out: + return retval; +} + +static int test_ioctl_close(struct inode* inode, struct file* filp) { + pr_alert("%s call.\n", __func__); + + if (filp->private_data) { + kfree(filp->private_data); + filp->private_data = NULL; + } + + return 0; +} + +static int test_ioctl_open(struct inode* inode, struct file* filp) { + struct test_ioctl_data* ioctl_data; + pr_alert("%s call.\n", __func__); + ioctl_data = kmalloc(sizeof(struct test_ioctl_data), GFP_KERNEL); + + if (ioctl_data == NULL) { + return -ENOMEM; + } + + rwlock_init(&ioctl_data->lock); + ioctl_data->val = 0xFF; + filp->private_data = ioctl_data; + return 0; +} + +struct file_operations fops = { + .owner = THIS_MODULE, + .open = test_ioctl_open, + .release = test_ioctl_close, + .read = test_ioctl_read, + .unlocked_ioctl = test_ioctl_ioctl, +}; + +static int ioctl_init(void) { + dev_t dev = MKDEV(test_ioctl_major, 0); + int alloc_ret = 0; + int cdev_ret = 0; + alloc_ret = alloc_chrdev_region(&dev, 0, num_of_dev, DRIVER_NAME); + + if (alloc_ret) { + goto error; + } + + test_ioctl_major = MAJOR(dev); + cdev_init(&test_ioctl_cdev, &fops); + cdev_ret = cdev_add(&test_ioctl_cdev, dev, num_of_dev); + + if (cdev_ret) { + goto error; + } + + pr_alert("%s driver(major: %d) installed.\n", DRIVER_NAME, test_ioctl_major); + return 0; +error: + + if (cdev_ret == 0) { + cdev_del(&test_ioctl_cdev); + } + + if (alloc_ret == 0) { + unregister_chrdev_region(dev, num_of_dev); + } + + return -1; +} + +static void ioctl_exit(void) { + dev_t dev = MKDEV(test_ioctl_major, 0); + cdev_del(&test_ioctl_cdev); + unregister_chrdev_region(dev, num_of_dev); + pr_alert("%s driver removed.\n", DRIVER_NAME); +} + +module_init(ioctl_init); +module_exit(ioctl_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Wang Chen Shu"); +MODULE_DESCRIPTION("This is test_ioctl module."); diff --git a/older_versions/4.9.11/examples/syscall.c b/older_versions/4.9.11/examples/syscall.c index 0b8952e..ecc06d9 100644 --- a/older_versions/4.9.11/examples/syscall.c +++ b/older_versions/4.9.11/examples/syscall.c @@ -25,7 +25,7 @@ #include #include -unsigned long **sys_call_table; +sys_call_ptr_t *sys_call_table_ptr; unsigned long original_cr0; /* @@ -87,15 +87,15 @@ asmlinkage int our_sys_open(const char *filename, int flags, int mode) return original_call(filename, flags, mode); } -static unsigned long **aquire_sys_call_table(void) +static sys_call_ptr_t *aquire_sys_call_table(void) { unsigned long int offset = PAGE_OFFSET; - unsigned long **sct; + sys_call_ptr_t *sct; while (offset < ULLONG_MAX) { - sct = (unsigned long **)offset; + sct = (sys_call_ptr_t*) offset; - if (sct[__NR_close] == (unsigned long *) sys_close) + if (sct[__NR_close] == (sys_call_ptr_t) sys_close) return sct; offset += sizeof(void *); @@ -106,7 +106,7 @@ static unsigned long **aquire_sys_call_table(void) static int __init syscall_start(void) { - if(!(sys_call_table = aquire_sys_call_table())) + if(!(sys_call_table_ptr = aquire_sys_call_table())) return -1; original_cr0 = read_cr0(); @@ -117,7 +117,7 @@ static int __init syscall_start(void) original_call = (void*)sys_call_table[__NR_open]; /* use our open function instead */ - sys_call_table[__NR_open] = (unsigned long *)our_sys_open; + sys_call_table_ptr[__NR_open] = (sys_call_ptr_t)our_sys_open; write_cr0(original_cr0); @@ -128,14 +128,14 @@ static int __init syscall_start(void) static void __exit syscall_end(void) { - if(!sys_call_table) { + if(!sys_call_table_ptr) { return; } /* * Return the system call back to normal */ - if (sys_call_table[__NR_open] != (unsigned long *)our_sys_open) { + if (sys_call_table_ptr[__NR_open] != (sys_call_ptr_t)our_sys_open) { printk(KERN_ALERT "Somebody else also played with the "); printk(KERN_ALERT "open system call\n"); printk(KERN_ALERT "The system may be left in "); @@ -143,7 +143,7 @@ static void __exit syscall_end(void) } write_cr0(original_cr0 & ~0x00010000); - sys_call_table[__NR_open] = (unsigned long *)original_call; + sys_call_table_ptr[__NR_open] = (sys_call_ptr_t)original_call; write_cr0(original_cr0); msleep(2000); From f49974968c9d19563a00c6a21f2219e834b40431 Mon Sep 17 00:00:00 2001 From: cisc7310x Date: Fri, 9 Feb 2018 19:07:53 -0500 Subject: [PATCH 3/3] reversed syscall for the 4.14 kernel --- 4.14.8/examples/syscall.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/4.14.8/examples/syscall.c b/4.14.8/examples/syscall.c index ccb901c..16222c5 100644 --- a/4.14.8/examples/syscall.c +++ b/4.14.8/examples/syscall.c @@ -25,7 +25,7 @@ #include #include -sys_call_ptr_t *sys_call_table_ptr; +unsigned long **sys_call_table; unsigned long original_cr0; /* @@ -87,18 +87,15 @@ asmlinkage int our_sys_open(const char *filename, int flags, int mode) return original_call(filename, flags, mode); } -static sys_call_ptr_t *aquire_sys_call_table(void) +static unsigned long **aquire_sys_call_table(void) { unsigned long int offset = PAGE_OFFSET; - /* unsigned long **sct; */ - sys_call_ptr_t *sct; + unsigned long **sct; while (offset < ULLONG_MAX) { - /* sct = (unsigned long **)offset; */ - sct = (sys_call_ptr_t *)offset; + sct = (unsigned long **)offset; - /* if (sct[__NR_close] == (unsigned long *) sys_close) */ - if (sct[__NR_close] == (sys_call_ptr_t) sys_close) + if (sct[__NR_close] == (unsigned long *) sys_close) return sct; offset += sizeof(void *); @@ -109,7 +106,7 @@ static sys_call_ptr_t *aquire_sys_call_table(void) static int __init syscall_start(void) { - if(!(sys_call_table_ptr = aquire_sys_call_table())) + if(!(sys_call_table = aquire_sys_call_table())) return -1; original_cr0 = read_cr0(); @@ -117,10 +114,10 @@ static int __init syscall_start(void) write_cr0(original_cr0 & ~0x00010000); /* keep track of the original open function */ - original_call = (void*)sys_call_table_ptr[__NR_open]; + original_call = (void*)sys_call_table[__NR_open]; /* use our open function instead */ - sys_call_table_ptr[__NR_open] = (sys_call_ptr_t)our_sys_open; + sys_call_table[__NR_open] = (unsigned long *)our_sys_open; write_cr0(original_cr0); @@ -131,14 +128,14 @@ static int __init syscall_start(void) static void __exit syscall_end(void) { - if(!sys_call_table_ptr) { + if(!sys_call_table) { return; } /* * Return the system call back to normal */ - if (sys_call_table_ptr[__NR_open] != (sys_call_ptr_t) our_sys_open) { + if (sys_call_table[__NR_open] != (unsigned long *)our_sys_open) { pr_alert("Somebody else also played with the "); pr_alert("open system call\n"); pr_alert("The system may be left in "); @@ -146,7 +143,7 @@ static void __exit syscall_end(void) } write_cr0(original_cr0 & ~0x00010000); - sys_call_table_ptr[__NR_open] = (sys_call_ptr_t)original_call; + sys_call_table[__NR_open] = (unsigned long *)original_call; write_cr0(original_cr0); msleep(2000);