1 // Copyright (C) 2013 Jann Horn <jann@thejh.net>
2 // This file is licensed under the GNU GPL v2 (see
10 #include <linux/module.h>
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/file.h>
15 #include <linux/ioctl.h>
16 #include <linux/uaccess.h>
17 #include <linux/miscdevice.h>
19 struct fetch_fops_args {
24 #define MOCTEL_FETCH_FOPS _IOR('m', 1, struct fetch_fops_args)
26 static int ioctl_open(struct inode *nodp, struct file *filp) {
30 static const struct file_operations dummy_fops = {};
32 static long ioctl_ioctl(struct file *filp_, unsigned int cmd, unsigned long arg) {
33 struct fetch_fops_args args;
35 const struct file_operations *fops;
37 if (cmd != MOCTEL_FETCH_FOPS) return -EINVAL;
38 if (copy_from_user(&args, (struct fetch_fops_args __user *)arg, sizeof(args))) return -EINVAL;
40 if (!filp) return -EBADF;
42 if (!fops) fops = &dummy_fops;
44 if (copy_to_user((struct file_operations __user *)args.retp, fops, sizeof(*fops))) return -EINVAL;
48 static int ioctl_release(struct inode *nodp, struct file *filp) {
52 static const struct file_operations ioctl_fops = {
54 .unlocked_ioctl = ioctl_ioctl,
56 .release = ioctl_release
59 static struct miscdevice ioctl_miscdev = {
65 static int __init init_ioctl(void) {
67 printk(KERN_INFO "loading ioctl helper\n");
69 ret = misc_register(&ioctl_miscdev);
73 static void __exit cleanup_ioctl(void) {
74 printk(KERN_INFO "unloading ioctl helper\n");
75 misc_deregister(&ioctl_miscdev);
78 module_init(init_ioctl);
79 module_exit(cleanup_ioctl);