A more useful way to interact with the driver
static ssize_t ioctl_handler(struct file *file, unsigned int cmd, unsigned long arg) {
printk("Command: %d; Argument: %d", cmd, arg);
return 0;
}#include <sys/ioctl.h>
// [...]
ioctl(fd, 0x100, 0x12345678); // data is a stringstatic struct file_operations fops = {
.ioctl = ioctl_handler
};static struct file_operations fops = {
.compat_ioctl = ioctl_handler,
.unlocked_ioctl = ioctl_handler
};#define DEVICE_NAME "intro"
#define CLASS_NAME "intro"
// setting up the device
int major;
static struct class* my_class = NULL;
static struct device* my_device = NULL;
static int __init intro_init(void) {
major = register_chrdev(0, DEVICE_NAME, &fops); // explained later
if ( major < 0 )
printk(KERN_ALERT "[Intro] Error assigning Major Number!");
// Register device class
my_class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(my_class)) {
unregister_chrdev(major, DEVICE_NAME);
printk(KERN_ALERT "[Intro] Failed to register device class\n");
}
// Register the device driver
my_device = device_create(my_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
if (IS_ERR(my_device)) {
class_destroy(my_class);
unregister_chrdev(major, DEVICE_NAME);
printk(KERN_ALERT "[Intro] Failed to create the device\n");
}
return 0;
}static void __exit intro_exit(void) {
device_destroy(my_class, MKDEV(major, 0)); // remove the device
class_unregister(my_class); // unregister the device class
class_destroy(my_class); // remove the device class
unregister_chrdev(major, DEVICE_NAME); // unregister the major number
printk(KERN_INFO "[Intro] Closing!\n");
}major = register_chrdev(0, DEVICE_NAME, &fops);static ssize_t intro_read(struct file *filp, char __user *buffer, size_t len, loff_t *off) {
printk(KERN_ALERT "reading...");
copy_to_user(buffer, "QWERTY", 6);
return 0;
}
static struct file_operations fops = {
.read = intro_read
};ssize_t read(int fd, void *buf, size_t count);#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/uaccess.h>
#define DEVICE_NAME "intro"
#define CLASS_NAME "intro"
MODULE_AUTHOR("ir0nstone");
MODULE_DESCRIPTION("Interactive Drivers");
MODULE_LICENSE("GPL");
// setting up the device
int major;
static struct class* my_class = NULL;
static struct device* my_device = NULL;
static ssize_t intro_read(struct file *filp, char __user *buffer, size_t len, loff_t *off) {
printk(KERN_ALERT "reading...");
copy_to_user(buffer, "QWERTY", 6);
return 0;
}
static struct file_operations fops = {
.read = intro_read
};
static int __init intro_init(void) {
major = register_chrdev(0, DEVICE_NAME, &fops);
if ( major < 0 )
printk(KERN_ALERT "[Intro] Error assigning Major Number!");
// Register device class
my_class = class_create(THIS_MODULE, CLASS_NAME);
if (IS_ERR(my_class)) {
unregister_chrdev(major, DEVICE_NAME);
printk(KERN_ALERT "[Intro] Failed to register device class\n");
}
// Register the device driver
my_device = device_create(my_class, NULL, MKDEV(major, 0), NULL, DEVICE_NAME);
if (IS_ERR(my_device)) {
class_destroy(my_class);
unregister_chrdev(major, DEVICE_NAME);
printk(KERN_ALERT "[Intro] Failed to create the device\n");
}
return 0;
}
static void __exit intro_exit(void) {
device_destroy(my_class, MKDEV(major, 0)); // remove the device
class_unregister(my_class); // unregister the device class
class_destroy(my_class); // remove the device class
unregister_chrdev(major, DEVICE_NAME); // unregister the major number
printk(KERN_INFO "[Intro] Closing!\n");
}
module_init(intro_init);
module_exit(intro_exit);
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
int main() {
int fd = open("/dev/intro", O_RDWR); // Open the device with RW access
printf("FD: %d\n", fd); // print the file descriptor
char buffer[6];
memset(&buffer, 'A', 6); // fill with As
printf("%s\n", buffer); // print
read(fd, buffer, 6); // read from module
printf("%s\n", buffer); // print again
}$ ./exploit
FD: 3
AAAAAA
QWERTY#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Mine!");
static int intro_init(void) {
printk(KERN_ALERT "Custom Module Started!\n");
return 0;
}
static void intro_exit(void) {
printk(KERN_ALERT "Custom Module Stopped :(\n");
}
module_init(intro_init);
module_exit(intro_exit);
obj-m += intro.o
all:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules$ make -j 8$ sudo insmod test.ko$ sudo dmesg | tail -n 1
[ 3645.657331] Custom Module Started!$ sudo rmmod test
$ sudo dmesg | tail -n 1
[ 4046.904898] Custom Module Stopped :(