summaryrefslogtreecommitdiffstats
path: root/drivers/misc
diff options
context:
space:
mode:
authorKees Cook <keescook@chromium.org>2017-10-20 09:31:27 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-20 09:50:55 -0400
commit31c5c870a1120960ec4157e6a5ea34686c77f6b8 (patch)
treea4cde07115cd89d21769c5d554f125d8099bb3d6 /drivers/misc
parent8caef1fa9176c4789b74c806434517b3adf7544a (diff)
lkdtm: Convert from jprobe to kprobe
The jprobe subsystem is being removed, so convert to using kprobe instead. Cc: Masami Hiramatsu <mhiramat@kernel.org> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/misc')
-rw-r--r--drivers/misc/lkdtm_core.c154
1 files changed, 45 insertions, 109 deletions
diff --git a/drivers/misc/lkdtm_core.c b/drivers/misc/lkdtm_core.c
index 981b3ef71e47..ed7f0c61c59a 100644
--- a/drivers/misc/lkdtm_core.c
+++ b/drivers/misc/lkdtm_core.c
@@ -56,122 +56,54 @@ static ssize_t direct_entry(struct file *f, const char __user *user_buf,
56 size_t count, loff_t *off); 56 size_t count, loff_t *off);
57 57
58#ifdef CONFIG_KPROBES 58#ifdef CONFIG_KPROBES
59static void lkdtm_handler(void); 59static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs);
60static ssize_t lkdtm_debugfs_entry(struct file *f, 60static ssize_t lkdtm_debugfs_entry(struct file *f,
61 const char __user *user_buf, 61 const char __user *user_buf,
62 size_t count, loff_t *off); 62 size_t count, loff_t *off);
63 63# define CRASHPOINT_KPROBE(_symbol) \
64 64 .kprobe = { \
65/* jprobe entry point handlers. */ 65 .symbol_name = (_symbol), \
66static unsigned int jp_do_irq(unsigned int irq) 66 .pre_handler = lkdtm_kprobe_handler, \
67{ 67 },
68 lkdtm_handler(); 68# define CRASHPOINT_WRITE(_symbol) \
69 jprobe_return(); 69 (_symbol) ? lkdtm_debugfs_entry : direct_entry
70 return 0; 70#else
71} 71# define CRASHPOINT_KPROBE(_symbol)
72 72# define CRASHPOINT_WRITE(_symbol) direct_entry
73static irqreturn_t jp_handle_irq_event(unsigned int irq,
74 struct irqaction *action)
75{
76 lkdtm_handler();
77 jprobe_return();
78 return 0;
79}
80
81static void jp_tasklet_action(struct softirq_action *a)
82{
83 lkdtm_handler();
84 jprobe_return();
85}
86
87static void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[])
88{
89 lkdtm_handler();
90 jprobe_return();
91}
92
93struct scan_control;
94
95static unsigned long jp_shrink_inactive_list(unsigned long max_scan,
96 struct zone *zone,
97 struct scan_control *sc)
98{
99 lkdtm_handler();
100 jprobe_return();
101 return 0;
102}
103
104static int jp_hrtimer_start(struct hrtimer *timer, ktime_t tim,
105 const enum hrtimer_mode mode)
106{
107 lkdtm_handler();
108 jprobe_return();
109 return 0;
110}
111
112static int jp_scsi_dispatch_cmd(struct scsi_cmnd *cmd)
113{
114 lkdtm_handler();
115 jprobe_return();
116 return 0;
117}
118
119# ifdef CONFIG_IDE
120static int jp_generic_ide_ioctl(ide_drive_t *drive, struct file *file,
121 struct block_device *bdev, unsigned int cmd,
122 unsigned long arg)
123{
124 lkdtm_handler();
125 jprobe_return();
126 return 0;
127}
128# endif
129#endif 73#endif
130 74
131/* Crash points */ 75/* Crash points */
132struct crashpoint { 76struct crashpoint {
133 const char *name; 77 const char *name;
134 const struct file_operations fops; 78 const struct file_operations fops;
135 struct jprobe jprobe; 79 struct kprobe kprobe;
136}; 80};
137 81
138#define CRASHPOINT(_name, _write, _symbol, _entry) \ 82#define CRASHPOINT(_name, _symbol) \
139 { \ 83 { \
140 .name = _name, \ 84 .name = _name, \
141 .fops = { \ 85 .fops = { \
142 .read = lkdtm_debugfs_read, \ 86 .read = lkdtm_debugfs_read, \
143 .llseek = generic_file_llseek, \ 87 .llseek = generic_file_llseek, \
144 .open = lkdtm_debugfs_open, \ 88 .open = lkdtm_debugfs_open, \
145 .write = _write, \ 89 .write = CRASHPOINT_WRITE(_symbol) \
146 }, \
147 .jprobe = { \
148 .kp.symbol_name = _symbol, \
149 .entry = (kprobe_opcode_t *)_entry, \
150 }, \ 90 }, \
91 CRASHPOINT_KPROBE(_symbol) \
151 } 92 }
152 93
153/* Define the possible places where we can trigger a crash point. */ 94/* Define the possible places where we can trigger a crash point. */
154struct crashpoint crashpoints[] = { 95static struct crashpoint crashpoints[] = {
155 CRASHPOINT("DIRECT", direct_entry, 96 CRASHPOINT("DIRECT", NULL),
156 NULL, NULL),
157#ifdef CONFIG_KPROBES 97#ifdef CONFIG_KPROBES
158 CRASHPOINT("INT_HARDWARE_ENTRY", lkdtm_debugfs_entry, 98 CRASHPOINT("INT_HARDWARE_ENTRY", "do_IRQ"),
159 "do_IRQ", jp_do_irq), 99 CRASHPOINT("INT_HW_IRQ_EN", "handle_IRQ_event"),
160 CRASHPOINT("INT_HW_IRQ_EN", lkdtm_debugfs_entry, 100 CRASHPOINT("INT_TASKLET_ENTRY", "tasklet_action"),
161 "handle_IRQ_event", jp_handle_irq_event), 101 CRASHPOINT("FS_DEVRW", "ll_rw_block"),
162 CRASHPOINT("INT_TASKLET_ENTRY", lkdtm_debugfs_entry, 102 CRASHPOINT("MEM_SWAPOUT", "shrink_inactive_list"),
163 "tasklet_action", jp_tasklet_action), 103 CRASHPOINT("TIMERADD", "hrtimer_start"),
164 CRASHPOINT("FS_DEVRW", lkdtm_debugfs_entry, 104 CRASHPOINT("SCSI_DISPATCH_CMD", "scsi_dispatch_cmd"),
165 "ll_rw_block", jp_ll_rw_block),
166 CRASHPOINT("MEM_SWAPOUT", lkdtm_debugfs_entry,
167 "shrink_inactive_list", jp_shrink_inactive_list),
168 CRASHPOINT("TIMERADD", lkdtm_debugfs_entry,
169 "hrtimer_start", jp_hrtimer_start),
170 CRASHPOINT("SCSI_DISPATCH_CMD", lkdtm_debugfs_entry,
171 "scsi_dispatch_cmd", jp_scsi_dispatch_cmd),
172# ifdef CONFIG_IDE 105# ifdef CONFIG_IDE
173 CRASHPOINT("IDE_CORE_CP", lkdtm_debugfs_entry, 106 CRASHPOINT("IDE_CORE_CP", "generic_ide_ioctl"),
174 "generic_ide_ioctl", jp_generic_ide_ioctl),
175# endif 107# endif
176#endif 108#endif
177}; 109};
@@ -254,8 +186,8 @@ struct crashtype crashtypes[] = {
254}; 186};
255 187
256 188
257/* Global jprobe entry and crashtype. */ 189/* Global kprobe entry and crashtype. */
258static struct jprobe *lkdtm_jprobe; 190static struct kprobe *lkdtm_kprobe;
259struct crashpoint *lkdtm_crashpoint; 191struct crashpoint *lkdtm_crashpoint;
260struct crashtype *lkdtm_crashtype; 192struct crashtype *lkdtm_crashtype;
261 193
@@ -298,7 +230,8 @@ static struct crashtype *find_crashtype(const char *name)
298 */ 230 */
299static noinline void lkdtm_do_action(struct crashtype *crashtype) 231static noinline void lkdtm_do_action(struct crashtype *crashtype)
300{ 232{
301 BUG_ON(!crashtype || !crashtype->func); 233 if (WARN_ON(!crashtype || !crashtype->func))
234 return;
302 crashtype->func(); 235 crashtype->func();
303} 236}
304 237
@@ -308,22 +241,22 @@ static int lkdtm_register_cpoint(struct crashpoint *crashpoint,
308 int ret; 241 int ret;
309 242
310 /* If this doesn't have a symbol, just call immediately. */ 243 /* If this doesn't have a symbol, just call immediately. */
311 if (!crashpoint->jprobe.kp.symbol_name) { 244 if (!crashpoint->kprobe.symbol_name) {
312 lkdtm_do_action(crashtype); 245 lkdtm_do_action(crashtype);
313 return 0; 246 return 0;
314 } 247 }
315 248
316 if (lkdtm_jprobe != NULL) 249 if (lkdtm_kprobe != NULL)
317 unregister_jprobe(lkdtm_jprobe); 250 unregister_kprobe(lkdtm_kprobe);
318 251
319 lkdtm_crashpoint = crashpoint; 252 lkdtm_crashpoint = crashpoint;
320 lkdtm_crashtype = crashtype; 253 lkdtm_crashtype = crashtype;
321 lkdtm_jprobe = &crashpoint->jprobe; 254 lkdtm_kprobe = &crashpoint->kprobe;
322 ret = register_jprobe(lkdtm_jprobe); 255 ret = register_kprobe(lkdtm_kprobe);
323 if (ret < 0) { 256 if (ret < 0) {
324 pr_info("Couldn't register jprobe %s\n", 257 pr_info("Couldn't register kprobe %s\n",
325 crashpoint->jprobe.kp.symbol_name); 258 crashpoint->kprobe.symbol_name);
326 lkdtm_jprobe = NULL; 259 lkdtm_kprobe = NULL;
327 lkdtm_crashpoint = NULL; 260 lkdtm_crashpoint = NULL;
328 lkdtm_crashtype = NULL; 261 lkdtm_crashtype = NULL;
329 } 262 }
@@ -336,13 +269,14 @@ static int lkdtm_register_cpoint(struct crashpoint *crashpoint,
336static int crash_count = DEFAULT_COUNT; 269static int crash_count = DEFAULT_COUNT;
337static DEFINE_SPINLOCK(crash_count_lock); 270static DEFINE_SPINLOCK(crash_count_lock);
338 271
339/* Called by jprobe entry points. */ 272/* Called by kprobe entry points. */
340static void lkdtm_handler(void) 273static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
341{ 274{
342 unsigned long flags; 275 unsigned long flags;
343 bool do_it = false; 276 bool do_it = false;
344 277
345 BUG_ON(!lkdtm_crashpoint || !lkdtm_crashtype); 278 if (WARN_ON(!lkdtm_crashpoint || !lkdtm_crashtype))
279 return 0;
346 280
347 spin_lock_irqsave(&crash_count_lock, flags); 281 spin_lock_irqsave(&crash_count_lock, flags);
348 crash_count--; 282 crash_count--;
@@ -357,6 +291,8 @@ static void lkdtm_handler(void)
357 291
358 if (do_it) 292 if (do_it)
359 lkdtm_do_action(lkdtm_crashtype); 293 lkdtm_do_action(lkdtm_crashtype);
294
295 return 0;
360} 296}
361 297
362static ssize_t lkdtm_debugfs_entry(struct file *f, 298static ssize_t lkdtm_debugfs_entry(struct file *f,
@@ -556,8 +492,8 @@ static void __exit lkdtm_module_exit(void)
556 /* Handle test-specific clean-up. */ 492 /* Handle test-specific clean-up. */
557 lkdtm_usercopy_exit(); 493 lkdtm_usercopy_exit();
558 494
559 if (lkdtm_jprobe != NULL) 495 if (lkdtm_kprobe != NULL)
560 unregister_jprobe(lkdtm_jprobe); 496 unregister_kprobe(lkdtm_kprobe);
561 497
562 pr_info("Crash point unregistered\n"); 498 pr_info("Crash point unregistered\n");
563} 499}