diff options
author | Kees Cook <keescook@chromium.org> | 2017-10-20 09:31:27 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-20 09:50:55 -0400 |
commit | 31c5c870a1120960ec4157e6a5ea34686c77f6b8 (patch) | |
tree | a4cde07115cd89d21769c5d554f125d8099bb3d6 /drivers/misc | |
parent | 8caef1fa9176c4789b74c806434517b3adf7544a (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.c | 154 |
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 |
59 | static void lkdtm_handler(void); | 59 | static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs); |
60 | static ssize_t lkdtm_debugfs_entry(struct file *f, | 60 | static 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), \ |
66 | static 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 | |
73 | static 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 | |||
81 | static void jp_tasklet_action(struct softirq_action *a) | ||
82 | { | ||
83 | lkdtm_handler(); | ||
84 | jprobe_return(); | ||
85 | } | ||
86 | |||
87 | static void jp_ll_rw_block(int rw, int nr, struct buffer_head *bhs[]) | ||
88 | { | ||
89 | lkdtm_handler(); | ||
90 | jprobe_return(); | ||
91 | } | ||
92 | |||
93 | struct scan_control; | ||
94 | |||
95 | static 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 | |||
104 | static 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 | |||
112 | static 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 | ||
120 | static 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 */ |
132 | struct crashpoint { | 76 | struct 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. */ |
154 | struct crashpoint crashpoints[] = { | 95 | static 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. */ |
258 | static struct jprobe *lkdtm_jprobe; | 190 | static struct kprobe *lkdtm_kprobe; |
259 | struct crashpoint *lkdtm_crashpoint; | 191 | struct crashpoint *lkdtm_crashpoint; |
260 | struct crashtype *lkdtm_crashtype; | 192 | struct crashtype *lkdtm_crashtype; |
261 | 193 | ||
@@ -298,7 +230,8 @@ static struct crashtype *find_crashtype(const char *name) | |||
298 | */ | 230 | */ |
299 | static noinline void lkdtm_do_action(struct crashtype *crashtype) | 231 | static 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, | |||
336 | static int crash_count = DEFAULT_COUNT; | 269 | static int crash_count = DEFAULT_COUNT; |
337 | static DEFINE_SPINLOCK(crash_count_lock); | 270 | static DEFINE_SPINLOCK(crash_count_lock); |
338 | 271 | ||
339 | /* Called by jprobe entry points. */ | 272 | /* Called by kprobe entry points. */ |
340 | static void lkdtm_handler(void) | 273 | static 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 | ||
362 | static ssize_t lkdtm_debugfs_entry(struct file *f, | 298 | static 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 | } |