anonymous_inode.c 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. /* https://github.com/cirosantilli/linux-kernel-module-cheat#anonymous-inode */
  2. #include <linux/anon_inodes.h>
  3. #include <linux/debugfs.h>
  4. #include <linux/errno.h> /* EFAULT */
  5. #include <linux/fs.h>
  6. #include <linux/kernel.h> /* min */
  7. #include <linux/module.h>
  8. #include <linux/printk.h> /* printk */
  9. #include <linux/uaccess.h> /* copy_from_user */
  10. #include <lkmc/anonymous_inode.h>
  11. static struct dentry *debugfs_file;
  12. static u32 myval = 1;
  13. static ssize_t read(struct file *filp, char __user *buf, size_t len, loff_t *off)
  14. {
  15. char kbuf[9];
  16. size_t ret;
  17. ret = snprintf(kbuf, sizeof(kbuf), "%x", myval);
  18. if (copy_to_user(buf, kbuf, ret)) {
  19. ret = -EFAULT;
  20. }
  21. myval <<= 4;
  22. if (myval == 0) {
  23. myval = 1;
  24. }
  25. return ret;
  26. }
  27. static const struct file_operations fops_anon = {
  28. .read = read,
  29. };
  30. static long unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long argp)
  31. {
  32. int fd;
  33. switch (cmd) {
  34. case LKMC_ANONYMOUS_INODE_GET_FD:
  35. fd = anon_inode_getfd(
  36. "todo_what_is_this_for",
  37. &fops_anon,
  38. NULL,
  39. O_RDONLY | O_CLOEXEC
  40. );
  41. if (copy_to_user((void __user *)argp, &fd, sizeof(fd))) {
  42. return -EFAULT;
  43. }
  44. break;
  45. default:
  46. return -EINVAL;
  47. break;
  48. }
  49. return 0;
  50. }
  51. static const struct file_operations fops_ioctl = {
  52. .owner = THIS_MODULE,
  53. .unlocked_ioctl = unlocked_ioctl
  54. };
  55. static int myinit(void)
  56. {
  57. debugfs_file = debugfs_create_file("lkmc_anonymous_inode", 0, NULL, NULL, &fops_ioctl);
  58. return 0;
  59. }
  60. static void myexit(void)
  61. {
  62. debugfs_remove(debugfs_file);
  63. }
  64. module_init(myinit)
  65. module_exit(myexit)
  66. MODULE_LICENSE("GPL");