#include #include #include #include #include #include #include #include static unsigned int test_type; module_param(test_type, uint, 0400); MODULE_PARM_DESC(test_type, "set to 1 to try to OOM (default 0)"); static int trigger_oops(void) { int *ptr = (int *)0; // 强制类型转换0地址为指针并尝试读取 printk(KERN_ALERT "Dereferenced NULL pointer value: %d\n", *ptr); return 0; } static int trigger_oom(void) { void *memory = NULL; size_t memory_size = 0; printk(KERN_INFO "oom_trigger: Initializing the oom_trigger LKM\n"); memory_size = 100*1024*1024; while (1) { // 尝试分配大块内存 memory = vmalloc(memory_size); if (!memory) { printk(KERN_ALERT "oom_trigger: Memory allocation failed\n"); break; } // 仅为防止编译器优化,实际不访问分配的内存 memset(memory, 0, memory_size); } return 0; } static int test_data = 0; static struct rcu_head test_rcu_head; static void bad_rcu_callback(struct rcu_head *head) { // 违规操作:在RCU回调函数中睡眠,这可能导致RCU grace period过长 msleep(1000); // 违规操作:修改被RCU保护的数据结构 test_data++; // 不应在RCU回调中修改全局变量 pr_info("Bad RCU callback executed\n"); } static void trigger_rcu(void) { pr_info("RCU error module loaded\n"); call_rcu(&test_rcu_head, bad_rcu_callback); } static int is_ready_thread1, is_ready_thread2; static struct task_struct *thread1; static struct task_struct *thread2; static DEFINE_MUTEX(mutex_a); static DEFINE_MUTEX(mutex_b); static int thread_func(void *data) { char *name = (char *) data; if (!strcmp(name, "Thread1")) { printk(KERN_INFO "%s: Acquiring mutex A...\n", name); mutex_lock(&mutex_a); is_ready_thread1 = 1; while (!is_ready_thread2); printk(KERN_INFO "%s: Got mutex A. Now trying to acquire mutex B...\n", name); mutex_lock(&mutex_b); // This will block, causing deadlock printk(KERN_INFO "%s: Got mutex B.\n", name); } else { printk(KERN_INFO "%s: Acquiring mutex B...\n", name); mutex_lock(&mutex_b); is_ready_thread2 = 1; while (!is_ready_thread1); printk(KERN_INFO "%s: Got mutex B. Now trying to acquire mutex A...\n", name); mutex_lock(&mutex_a); // This will block, causing deadlock printk(KERN_INFO "%s: Got mutex A.\n", name); } return 0; } static int trigger_deadlock(void) { thread1 = kthread_run(thread_func, (void *) "Thread1", "thread1"); if (IS_ERR(thread1)) { printk(KERN_ERR "Failed to create thread1\n"); return PTR_ERR(thread1); } thread2 = kthread_run(thread_func, (void *) "Thread2", "thread2"); if (IS_ERR(thread2)) { printk(KERN_ERR "Failed to create thread2\n"); kthread_stop(thread1); return PTR_ERR(thread2); } return 0; } static int trigger_init(void) { if (test_type == 0) trigger_oops(); else if (test_type == 1) trigger_oom(); else if (test_type == 2) trigger_rcu(); else if (test_type == 3) trigger_deadlock(); return 0; // 加载模块不应该有返回值,但这里返回0避免编译警告。 } static void __exit trigger_exit(void) { if (test_type == 3) { kthread_stop(thread1); kthread_stop(thread2); printk(KERN_INFO "Deadlock trigger exit.\n"); } } module_init(trigger_init); module_exit(trigger_exit); MODULE_LICENSE("GPL");