summaryrefslogtreecommitdiffstats
path: root/misc-modules/faulty.c
diff options
context:
space:
mode:
authorJavier Martinez Canillas <martinez.javier@gmail.com>2010-11-27 07:49:17 +0100
committerJavier Martinez Canillas <martinez.javier@gmail.com>2010-11-27 07:49:17 +0100
commitab121f379a3cff458c90e6f480ba4bb68c8733dd (patch)
treea9851af109ee83646d108bc247d03b131461b764 /misc-modules/faulty.c
downloadldd3-ab121f379a3cff458c90e6f480ba4bb68c8733dd.tar.gz
Linux Device Drivers 3 examples
Diffstat (limited to 'misc-modules/faulty.c')
-rw-r--r--misc-modules/faulty.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/misc-modules/faulty.c b/misc-modules/faulty.c
new file mode 100644
index 0000000..48c1850
--- /dev/null
+++ b/misc-modules/faulty.c
@@ -0,0 +1,89 @@
+/*
+ * faulty.c -- a module which generates an oops when read
+ *
+ * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet
+ * Copyright (C) 2001 O'Reilly & Associates
+ *
+ * The source code in this file can be freely used, adapted,
+ * and redistributed in source or binary form, so long as an
+ * acknowledgment appears in derived source files. The citation
+ * should list that the code comes from the book "Linux Device
+ * Drivers" by Alessandro Rubini and Jonathan Corbet, published
+ * by O'Reilly & Associates. No warranty is attached;
+ * we cannot take responsibility for errors or fitness for use.
+ *
+ * $Id: faulty.c,v 1.3 2004/09/26 07:02:43 gregkh Exp $
+ */
+
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/kernel.h> /* printk() */
+#include <linux/fs.h> /* everything... */
+#include <linux/types.h> /* size_t */
+#include <asm/uaccess.h>
+
+MODULE_LICENSE("Dual BSD/GPL");
+
+
+int faulty_major = 0;
+
+ssize_t faulty_read(struct file *filp, char __user *buf,
+ size_t count, loff_t *pos)
+{
+ int ret;
+ char stack_buf[4];
+
+ /* Let's try a buffer overflow */
+ memset(stack_buf, 0xff, 20);
+ if (count > 4)
+ count = 4; /* copy 4 bytes to the user */
+ ret = copy_to_user(buf, stack_buf, count);
+ if (!ret)
+ return count;
+ return ret;
+}
+
+ssize_t faulty_write (struct file *filp, const char __user *buf, size_t count,
+ loff_t *pos)
+{
+ /* make a simple fault by dereferencing a NULL pointer */
+ *(int *)0 = 0;
+ return 0;
+}
+
+
+
+struct file_operations faulty_fops = {
+ .read = faulty_read,
+ .write = faulty_write,
+ .owner = THIS_MODULE
+};
+
+
+int faulty_init(void)
+{
+ int result;
+
+ /*
+ * Register your major, and accept a dynamic number
+ */
+ result = register_chrdev(faulty_major, "faulty", &faulty_fops);
+ if (result < 0)
+ return result;
+ if (faulty_major == 0)
+ faulty_major = result; /* dynamic */
+
+ return 0;
+}
+
+void faulty_cleanup(void)
+{
+ unregister_chrdev(faulty_major, "faulty");
+}
+
+module_init(faulty_init);
+module_exit(faulty_cleanup);
+