GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / misc / lkdtm / core.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Linux Kernel Dump Test Module for testing kernel crashes conditions:
4  * induces system failures at predefined crashpoints and under predefined
5  * operational conditions in order to evaluate the reliability of kernel
6  * sanity checking and crash dumps obtained using different dumping
7  * solutions.
8  *
9  * Copyright (C) IBM Corporation, 2006
10  *
11  * Author: Ankita Garg <ankita@in.ibm.com>
12  *
13  * It is adapted from the Linux Kernel Dump Test Tool by
14  * Fernando Luis Vazquez Cao <http://lkdtt.sourceforge.net>
15  *
16  * Debugfs support added by Simon Kagstrom <simon.kagstrom@netinsight.net>
17  *
18  * See Documentation/fault-injection/provoke-crashes.rst for instructions
19  */
20 #include "lkdtm.h"
21 #include <linux/fs.h>
22 #include <linux/module.h>
23 #include <linux/buffer_head.h>
24 #include <linux/kprobes.h>
25 #include <linux/list.h>
26 #include <linux/init.h>
27 #include <linux/slab.h>
28 #include <linux/debugfs.h>
29 #include <linux/utsname.h>
30
31 #define DEFAULT_COUNT 10
32
33 static int lkdtm_debugfs_open(struct inode *inode, struct file *file);
34 static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
35                 size_t count, loff_t *off);
36 static ssize_t direct_entry(struct file *f, const char __user *user_buf,
37                             size_t count, loff_t *off);
38
39 #ifdef CONFIG_KPROBES
40 static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs);
41 static ssize_t lkdtm_debugfs_entry(struct file *f,
42                                    const char __user *user_buf,
43                                    size_t count, loff_t *off);
44 # define CRASHPOINT_KPROBE(_symbol)                             \
45                 .kprobe = {                                     \
46                         .symbol_name = (_symbol),               \
47                         .pre_handler = lkdtm_kprobe_handler,    \
48                 },
49 # define CRASHPOINT_WRITE(_symbol)                              \
50                 (_symbol) ? lkdtm_debugfs_entry : direct_entry
51 #else
52 # define CRASHPOINT_KPROBE(_symbol)
53 # define CRASHPOINT_WRITE(_symbol)              direct_entry
54 #endif
55
56 /* Crash points */
57 struct crashpoint {
58         const char *name;
59         const struct file_operations fops;
60         struct kprobe kprobe;
61 };
62
63 #define CRASHPOINT(_name, _symbol)                              \
64         {                                                       \
65                 .name = _name,                                  \
66                 .fops = {                                       \
67                         .read   = lkdtm_debugfs_read,           \
68                         .llseek = generic_file_llseek,          \
69                         .open   = lkdtm_debugfs_open,           \
70                         .write  = CRASHPOINT_WRITE(_symbol)     \
71                 },                                              \
72                 CRASHPOINT_KPROBE(_symbol)                      \
73         }
74
75 /* Define the possible places where we can trigger a crash point. */
76 static struct crashpoint crashpoints[] = {
77         CRASHPOINT("DIRECT",             NULL),
78 #ifdef CONFIG_KPROBES
79         CRASHPOINT("INT_HARDWARE_ENTRY", "do_IRQ"),
80         CRASHPOINT("INT_HW_IRQ_EN",      "handle_irq_event"),
81         CRASHPOINT("INT_TASKLET_ENTRY",  "tasklet_action"),
82         CRASHPOINT("FS_SUBMIT_BH",               "submit_bh"),
83         CRASHPOINT("MEM_SWAPOUT",        "shrink_inactive_list"),
84         CRASHPOINT("TIMERADD",           "hrtimer_start"),
85         CRASHPOINT("SCSI_QUEUE_RQ",      "scsi_queue_rq"),
86 #endif
87 };
88
89 /* List of possible types for crashes that can be triggered. */
90 static const struct crashtype_category *crashtype_categories[] = {
91         &bugs_crashtypes,
92         &heap_crashtypes,
93         &perms_crashtypes,
94         &refcount_crashtypes,
95         &usercopy_crashtypes,
96         &stackleak_crashtypes,
97         &cfi_crashtypes,
98         &fortify_crashtypes,
99 #ifdef CONFIG_PPC_64S_HASH_MMU
100         &powerpc_crashtypes,
101 #endif
102 };
103
104 /* Global kprobe entry and crashtype. */
105 static struct kprobe *lkdtm_kprobe;
106 static struct crashpoint *lkdtm_crashpoint;
107 static const struct crashtype *lkdtm_crashtype;
108
109 /* Module parameters */
110 static int recur_count = -1;
111 module_param(recur_count, int, 0644);
112 MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test");
113
114 static char* cpoint_name;
115 module_param(cpoint_name, charp, 0444);
116 MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
117
118 static char* cpoint_type;
119 module_param(cpoint_type, charp, 0444);
120 MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\
121                                 "hitting the crash point");
122
123 static int cpoint_count = DEFAULT_COUNT;
124 module_param(cpoint_count, int, 0644);
125 MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\
126                                 "crash point is to be hit to trigger action");
127
128 /*
129  * For test debug reporting when CI systems provide terse summaries.
130  * TODO: Remove this once reasonable reporting exists in most CI systems:
131  * https://lore.kernel.org/lkml/CAHk-=wiFvfkoFixTapvvyPMN9pq5G-+Dys2eSyBa1vzDGAO5+A@mail.gmail.com
132  */
133 char *lkdtm_kernel_info;
134
135 /* Return the crashtype number or NULL if the name is invalid */
136 static const struct crashtype *find_crashtype(const char *name)
137 {
138         int cat, idx;
139
140         for (cat = 0; cat < ARRAY_SIZE(crashtype_categories); cat++) {
141                 for (idx = 0; idx < crashtype_categories[cat]->len; idx++) {
142                         struct crashtype *crashtype;
143
144                         crashtype = &crashtype_categories[cat]->crashtypes[idx];
145                         if (!strcmp(name, crashtype->name))
146                                 return crashtype;
147                 }
148         }
149
150         return NULL;
151 }
152
153 /*
154  * This is forced noinline just so it distinctly shows up in the stackdump
155  * which makes validation of expected lkdtm crashes easier.
156  */
157 static noinline void lkdtm_do_action(const struct crashtype *crashtype)
158 {
159         if (WARN_ON(!crashtype || !crashtype->func))
160                 return;
161         crashtype->func();
162 }
163
164 static int lkdtm_register_cpoint(struct crashpoint *crashpoint,
165                                  const struct crashtype *crashtype)
166 {
167         int ret;
168
169         /* If this doesn't have a symbol, just call immediately. */
170         if (!crashpoint->kprobe.symbol_name) {
171                 lkdtm_do_action(crashtype);
172                 return 0;
173         }
174
175         if (lkdtm_kprobe != NULL)
176                 unregister_kprobe(lkdtm_kprobe);
177
178         lkdtm_crashpoint = crashpoint;
179         lkdtm_crashtype = crashtype;
180         lkdtm_kprobe = &crashpoint->kprobe;
181         ret = register_kprobe(lkdtm_kprobe);
182         if (ret < 0) {
183                 pr_info("Couldn't register kprobe %s\n",
184                         crashpoint->kprobe.symbol_name);
185                 lkdtm_kprobe = NULL;
186                 lkdtm_crashpoint = NULL;
187                 lkdtm_crashtype = NULL;
188         }
189
190         return ret;
191 }
192
193 #ifdef CONFIG_KPROBES
194 /* Global crash counter and spinlock. */
195 static int crash_count = DEFAULT_COUNT;
196 static DEFINE_SPINLOCK(crash_count_lock);
197
198 /* Called by kprobe entry points. */
199 static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
200 {
201         unsigned long flags;
202         bool do_it = false;
203
204         if (WARN_ON(!lkdtm_crashpoint || !lkdtm_crashtype))
205                 return 0;
206
207         spin_lock_irqsave(&crash_count_lock, flags);
208         crash_count--;
209         pr_info("Crash point %s of type %s hit, trigger in %d rounds\n",
210                 lkdtm_crashpoint->name, lkdtm_crashtype->name, crash_count);
211
212         if (crash_count == 0) {
213                 do_it = true;
214                 crash_count = cpoint_count;
215         }
216         spin_unlock_irqrestore(&crash_count_lock, flags);
217
218         if (do_it)
219                 lkdtm_do_action(lkdtm_crashtype);
220
221         return 0;
222 }
223
224 static ssize_t lkdtm_debugfs_entry(struct file *f,
225                                    const char __user *user_buf,
226                                    size_t count, loff_t *off)
227 {
228         struct crashpoint *crashpoint = file_inode(f)->i_private;
229         const struct crashtype *crashtype = NULL;
230         char *buf;
231         int err;
232
233         if (count >= PAGE_SIZE)
234                 return -EINVAL;
235
236         buf = (char *)__get_free_page(GFP_KERNEL);
237         if (!buf)
238                 return -ENOMEM;
239         if (copy_from_user(buf, user_buf, count)) {
240                 free_page((unsigned long) buf);
241                 return -EFAULT;
242         }
243         /* NULL-terminate and remove enter */
244         buf[count] = '\0';
245         strim(buf);
246
247         crashtype = find_crashtype(buf);
248         free_page((unsigned long)buf);
249
250         if (!crashtype)
251                 return -EINVAL;
252
253         err = lkdtm_register_cpoint(crashpoint, crashtype);
254         if (err < 0)
255                 return err;
256
257         *off += count;
258
259         return count;
260 }
261 #endif
262
263 /* Generic read callback that just prints out the available crash types */
264 static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
265                 size_t count, loff_t *off)
266 {
267         int n, cat, idx;
268         ssize_t out;
269         char *buf;
270
271         buf = (char *)__get_free_page(GFP_KERNEL);
272         if (buf == NULL)
273                 return -ENOMEM;
274
275         n = scnprintf(buf, PAGE_SIZE, "Available crash types:\n");
276
277         for (cat = 0; cat < ARRAY_SIZE(crashtype_categories); cat++) {
278                 for (idx = 0; idx < crashtype_categories[cat]->len; idx++) {
279                         struct crashtype *crashtype;
280
281                         crashtype = &crashtype_categories[cat]->crashtypes[idx];
282                         n += scnprintf(buf + n, PAGE_SIZE - n, "%s\n",
283                                       crashtype->name);
284                 }
285         }
286         buf[n] = '\0';
287
288         out = simple_read_from_buffer(user_buf, count, off,
289                                       buf, n);
290         free_page((unsigned long) buf);
291
292         return out;
293 }
294
295 static int lkdtm_debugfs_open(struct inode *inode, struct file *file)
296 {
297         return 0;
298 }
299
300 /* Special entry to just crash directly. Available without KPROBEs */
301 static ssize_t direct_entry(struct file *f, const char __user *user_buf,
302                 size_t count, loff_t *off)
303 {
304         const struct crashtype *crashtype;
305         char *buf;
306
307         if (count >= PAGE_SIZE)
308                 return -EINVAL;
309         if (count < 1)
310                 return -EINVAL;
311
312         buf = (char *)__get_free_page(GFP_KERNEL);
313         if (!buf)
314                 return -ENOMEM;
315         if (copy_from_user(buf, user_buf, count)) {
316                 free_page((unsigned long) buf);
317                 return -EFAULT;
318         }
319         /* NULL-terminate and remove enter */
320         buf[count] = '\0';
321         strim(buf);
322
323         crashtype = find_crashtype(buf);
324         free_page((unsigned long) buf);
325         if (!crashtype)
326                 return -EINVAL;
327
328         pr_info("Performing direct entry %s\n", crashtype->name);
329         lkdtm_do_action(crashtype);
330         *off += count;
331
332         return count;
333 }
334
335 #ifndef MODULE
336 /*
337  * To avoid needing to export parse_args(), just don't use this code
338  * when LKDTM is built as a module.
339  */
340 struct check_cmdline_args {
341         const char *param;
342         int value;
343 };
344
345 static int lkdtm_parse_one(char *param, char *val,
346                            const char *unused, void *arg)
347 {
348         struct check_cmdline_args *args = arg;
349
350         /* short circuit if we already found a value. */
351         if (args->value != -ESRCH)
352                 return 0;
353         if (strncmp(param, args->param, strlen(args->param)) == 0) {
354                 bool bool_result;
355                 int ret;
356
357                 ret = kstrtobool(val, &bool_result);
358                 if (ret == 0)
359                         args->value = bool_result;
360         }
361         return 0;
362 }
363
364 int lkdtm_check_bool_cmdline(const char *param)
365 {
366         char *command_line;
367         struct check_cmdline_args args = {
368                 .param = param,
369                 .value = -ESRCH,
370         };
371
372         command_line = kstrdup(saved_command_line, GFP_KERNEL);
373         if (!command_line)
374                 return -ENOMEM;
375
376         parse_args("Setting sysctl args", command_line,
377                    NULL, 0, -1, -1, &args, lkdtm_parse_one);
378
379         kfree(command_line);
380
381         return args.value;
382 }
383 #endif
384
385 static struct dentry *lkdtm_debugfs_root;
386
387 static int __init lkdtm_module_init(void)
388 {
389         struct crashpoint *crashpoint = NULL;
390         const struct crashtype *crashtype = NULL;
391         int ret;
392         int i;
393
394         /* Neither or both of these need to be set */
395         if ((cpoint_type || cpoint_name) && !(cpoint_type && cpoint_name)) {
396                 pr_err("Need both cpoint_type and cpoint_name or neither\n");
397                 return -EINVAL;
398         }
399
400         if (cpoint_type) {
401                 crashtype = find_crashtype(cpoint_type);
402                 if (!crashtype) {
403                         pr_err("Unknown crashtype '%s'\n", cpoint_type);
404                         return -EINVAL;
405                 }
406         }
407
408         if (cpoint_name) {
409                 for (i = 0; i < ARRAY_SIZE(crashpoints); i++) {
410                         if (!strcmp(cpoint_name, crashpoints[i].name))
411                                 crashpoint = &crashpoints[i];
412                 }
413
414                 /* Refuse unknown crashpoints. */
415                 if (!crashpoint) {
416                         pr_err("Invalid crashpoint %s\n", cpoint_name);
417                         return -EINVAL;
418                 }
419         }
420
421 #ifdef CONFIG_KPROBES
422         /* Set crash count. */
423         crash_count = cpoint_count;
424 #endif
425
426         /* Common initialization. */
427         lkdtm_kernel_info = kasprintf(GFP_KERNEL, "kernel (%s %s)",
428                                       init_uts_ns.name.release,
429                                       init_uts_ns.name.machine);
430
431         /* Handle test-specific initialization. */
432         lkdtm_bugs_init(&recur_count);
433         lkdtm_perms_init();
434         lkdtm_usercopy_init();
435         lkdtm_heap_init();
436
437         /* Register debugfs interface */
438         lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
439
440         /* Install debugfs trigger files. */
441         for (i = 0; i < ARRAY_SIZE(crashpoints); i++) {
442                 struct crashpoint *cur = &crashpoints[i];
443
444                 debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, cur,
445                                     &cur->fops);
446         }
447
448         /* Install crashpoint if one was selected. */
449         if (crashpoint) {
450                 ret = lkdtm_register_cpoint(crashpoint, crashtype);
451                 if (ret < 0) {
452                         pr_info("Invalid crashpoint %s\n", crashpoint->name);
453                         goto out_err;
454                 }
455                 pr_info("Crash point %s of type %s registered\n",
456                         crashpoint->name, cpoint_type);
457         } else {
458                 pr_info("No crash points registered, enable through debugfs\n");
459         }
460
461         return 0;
462
463 out_err:
464         debugfs_remove_recursive(lkdtm_debugfs_root);
465         return ret;
466 }
467
468 static void __exit lkdtm_module_exit(void)
469 {
470         debugfs_remove_recursive(lkdtm_debugfs_root);
471
472         /* Handle test-specific clean-up. */
473         lkdtm_heap_exit();
474         lkdtm_usercopy_exit();
475
476         if (lkdtm_kprobe != NULL)
477                 unregister_kprobe(lkdtm_kprobe);
478
479         kfree(lkdtm_kernel_info);
480
481         pr_info("Crash point unregistered\n");
482 }
483
484 module_init(lkdtm_module_init);
485 module_exit(lkdtm_module_exit);
486
487 MODULE_LICENSE("GPL");
488 MODULE_DESCRIPTION("Kernel crash testing module");