/* Special entry to just crash directly. Available without KPROBEs */ static ssize_t direct_entry(struct file *f, const char __user *user_buf, size_t count, loff_t *off) { enum ctype type; char *buf; if (count >= PAGE_SIZE) return -EINVAL; if (count < 1) return -EINVAL; buf = (char *)__get_free_page(GFP_KERNEL); if (!buf) return -ENOMEM; if (copy_from_user(buf, user_buf, count)) { free_page((unsigned long) buf); return -EFAULT; } /* NULL-terminate and remove enter */ buf[count] = '\0'; strim(buf); type = parse_cp_type(buf, count); free_page((unsigned long) buf); if (type == CT_NONE) return -EINVAL; pr_info("Performing direct entry %s\n", cp_type_to_str(type)); lkdtm_do_action(type); *off += count; return count; }
static void lkdtm_handler(void) { count--; printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n", cp_name_to_str(cpoint), cp_type_to_str(cptype), count); if (count == 0) { lkdtm_do_action(cptype); count = cpoint_count; } }
static void lkdtm_handler(void) { unsigned long flags; spin_lock_irqsave(&count_lock, flags); count--; // printk(KERN_INFO "lkdtm: Crash point %s of type %s hit, trigger in %d rounds\n", ; if (count == 0) { lkdtm_do_action(cptype); count = cpoint_count; } spin_unlock_irqrestore(&count_lock, flags); }
static void lkdtm_handler(void) { unsigned long flags; bool do_it = false; spin_lock_irqsave(&count_lock, flags); count--; pr_info("Crash point %s of type %s hit, trigger in %d rounds\n", cp_name_to_str(cpoint), cp_type_to_str(cptype), count); if (count == 0) { do_it = true; count = cpoint_count; } spin_unlock_irqrestore(&count_lock, flags); if (do_it) lkdtm_do_action(cptype); }
static int lkdtm_register_cpoint(enum cname which) { int ret; cpoint = CN_INVALID; if (lkdtm.entry != NULL) unregister_jprobe(&lkdtm); switch (which) { case CN_DIRECT: lkdtm_do_action(cptype); return 0; case CN_INT_HARDWARE_ENTRY: lkdtm.kp.symbol_name = "do_IRQ"; lkdtm.entry = (kprobe_opcode_t*) jp_do_irq; break; case CN_INT_HW_IRQ_EN: lkdtm.kp.symbol_name = "handle_IRQ_event"; lkdtm.entry = (kprobe_opcode_t*) jp_handle_irq_event; break; case CN_INT_TASKLET_ENTRY: lkdtm.kp.symbol_name = "tasklet_action"; lkdtm.entry = (kprobe_opcode_t*) jp_tasklet_action; break; case CN_FS_DEVRW: lkdtm.kp.symbol_name = "ll_rw_block"; lkdtm.entry = (kprobe_opcode_t*) jp_ll_rw_block; break; case CN_MEM_SWAPOUT: lkdtm.kp.symbol_name = "shrink_inactive_list"; lkdtm.entry = (kprobe_opcode_t*) jp_shrink_inactive_list; break; case CN_TIMERADD: lkdtm.kp.symbol_name = "hrtimer_start"; lkdtm.entry = (kprobe_opcode_t*) jp_hrtimer_start; break; case CN_SCSI_DISPATCH_CMD: lkdtm.kp.symbol_name = "scsi_dispatch_cmd"; lkdtm.entry = (kprobe_opcode_t*) jp_scsi_dispatch_cmd; break; case CN_IDE_CORE_CP: #ifdef CONFIG_IDE lkdtm.kp.symbol_name = "generic_ide_ioctl"; lkdtm.entry = (kprobe_opcode_t*) jp_generic_ide_ioctl; #else pr_info("Crash point not available\n"); return -EINVAL; #endif break; default: pr_info("Invalid Crash Point\n"); return -EINVAL; } cpoint = which; if ((ret = register_jprobe(&lkdtm)) < 0) { pr_info("Couldn't register jprobe\n"); cpoint = CN_INVALID; } return ret; }