linux/drivers/misc/lkdtm/core.c
<<
>>
Prefs
   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
  33static int lkdtm_debugfs_open(struct inode *inode, struct file *file);
  34static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
  35                size_t count, loff_t *off);
  36static ssize_t direct_entry(struct file *f, const char __user *user_buf,
  37                            size_t count, loff_t *off);
  38
  39#ifdef CONFIG_KPROBES
  40static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs);
  41static 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 */
  57struct 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. */
  76static 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_DEVRW",           "ll_rw_block"),
  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
  90/* Crash types. */
  91struct crashtype {
  92        const char *name;
  93        void (*func)(void);
  94};
  95
  96#define CRASHTYPE(_name)                        \
  97        {                                       \
  98                .name = __stringify(_name),     \
  99                .func = lkdtm_ ## _name,        \
 100        }
 101
 102/* Define the possible types of crashes that can be triggered. */
 103static const struct crashtype crashtypes[] = {
 104        CRASHTYPE(PANIC),
 105        CRASHTYPE(BUG),
 106        CRASHTYPE(WARNING),
 107        CRASHTYPE(WARNING_MESSAGE),
 108        CRASHTYPE(EXCEPTION),
 109        CRASHTYPE(LOOP),
 110        CRASHTYPE(EXHAUST_STACK),
 111        CRASHTYPE(CORRUPT_STACK),
 112        CRASHTYPE(CORRUPT_STACK_STRONG),
 113        CRASHTYPE(REPORT_STACK),
 114        CRASHTYPE(CORRUPT_LIST_ADD),
 115        CRASHTYPE(CORRUPT_LIST_DEL),
 116        CRASHTYPE(STACK_GUARD_PAGE_LEADING),
 117        CRASHTYPE(STACK_GUARD_PAGE_TRAILING),
 118        CRASHTYPE(UNSET_SMEP),
 119        CRASHTYPE(CORRUPT_PAC),
 120        CRASHTYPE(UNALIGNED_LOAD_STORE_WRITE),
 121        CRASHTYPE(SLAB_LINEAR_OVERFLOW),
 122        CRASHTYPE(VMALLOC_LINEAR_OVERFLOW),
 123        CRASHTYPE(WRITE_AFTER_FREE),
 124        CRASHTYPE(READ_AFTER_FREE),
 125        CRASHTYPE(WRITE_BUDDY_AFTER_FREE),
 126        CRASHTYPE(READ_BUDDY_AFTER_FREE),
 127        CRASHTYPE(SLAB_INIT_ON_ALLOC),
 128        CRASHTYPE(BUDDY_INIT_ON_ALLOC),
 129        CRASHTYPE(SLAB_FREE_DOUBLE),
 130        CRASHTYPE(SLAB_FREE_CROSS),
 131        CRASHTYPE(SLAB_FREE_PAGE),
 132        CRASHTYPE(SOFTLOCKUP),
 133        CRASHTYPE(HARDLOCKUP),
 134        CRASHTYPE(SPINLOCKUP),
 135        CRASHTYPE(HUNG_TASK),
 136        CRASHTYPE(OVERFLOW_SIGNED),
 137        CRASHTYPE(OVERFLOW_UNSIGNED),
 138        CRASHTYPE(ARRAY_BOUNDS),
 139        CRASHTYPE(EXEC_DATA),
 140        CRASHTYPE(EXEC_STACK),
 141        CRASHTYPE(EXEC_KMALLOC),
 142        CRASHTYPE(EXEC_VMALLOC),
 143        CRASHTYPE(EXEC_RODATA),
 144        CRASHTYPE(EXEC_USERSPACE),
 145        CRASHTYPE(EXEC_NULL),
 146        CRASHTYPE(ACCESS_USERSPACE),
 147        CRASHTYPE(ACCESS_NULL),
 148        CRASHTYPE(WRITE_RO),
 149        CRASHTYPE(WRITE_RO_AFTER_INIT),
 150        CRASHTYPE(WRITE_KERN),
 151        CRASHTYPE(REFCOUNT_INC_OVERFLOW),
 152        CRASHTYPE(REFCOUNT_ADD_OVERFLOW),
 153        CRASHTYPE(REFCOUNT_INC_NOT_ZERO_OVERFLOW),
 154        CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_OVERFLOW),
 155        CRASHTYPE(REFCOUNT_DEC_ZERO),
 156        CRASHTYPE(REFCOUNT_DEC_NEGATIVE),
 157        CRASHTYPE(REFCOUNT_DEC_AND_TEST_NEGATIVE),
 158        CRASHTYPE(REFCOUNT_SUB_AND_TEST_NEGATIVE),
 159        CRASHTYPE(REFCOUNT_INC_ZERO),
 160        CRASHTYPE(REFCOUNT_ADD_ZERO),
 161        CRASHTYPE(REFCOUNT_INC_SATURATED),
 162        CRASHTYPE(REFCOUNT_DEC_SATURATED),
 163        CRASHTYPE(REFCOUNT_ADD_SATURATED),
 164        CRASHTYPE(REFCOUNT_INC_NOT_ZERO_SATURATED),
 165        CRASHTYPE(REFCOUNT_ADD_NOT_ZERO_SATURATED),
 166        CRASHTYPE(REFCOUNT_DEC_AND_TEST_SATURATED),
 167        CRASHTYPE(REFCOUNT_SUB_AND_TEST_SATURATED),
 168        CRASHTYPE(REFCOUNT_TIMING),
 169        CRASHTYPE(ATOMIC_TIMING),
 170        CRASHTYPE(USERCOPY_HEAP_SIZE_TO),
 171        CRASHTYPE(USERCOPY_HEAP_SIZE_FROM),
 172        CRASHTYPE(USERCOPY_HEAP_WHITELIST_TO),
 173        CRASHTYPE(USERCOPY_HEAP_WHITELIST_FROM),
 174        CRASHTYPE(USERCOPY_STACK_FRAME_TO),
 175        CRASHTYPE(USERCOPY_STACK_FRAME_FROM),
 176        CRASHTYPE(USERCOPY_STACK_BEYOND),
 177        CRASHTYPE(USERCOPY_KERNEL),
 178        CRASHTYPE(STACKLEAK_ERASING),
 179        CRASHTYPE(CFI_FORWARD_PROTO),
 180        CRASHTYPE(FORTIFIED_OBJECT),
 181        CRASHTYPE(FORTIFIED_SUBOBJECT),
 182        CRASHTYPE(FORTIFIED_STRSCPY),
 183        CRASHTYPE(DOUBLE_FAULT),
 184#ifdef CONFIG_PPC_BOOK3S_64
 185        CRASHTYPE(PPC_SLB_MULTIHIT),
 186#endif
 187};
 188
 189
 190/* Global kprobe entry and crashtype. */
 191static struct kprobe *lkdtm_kprobe;
 192static struct crashpoint *lkdtm_crashpoint;
 193static const struct crashtype *lkdtm_crashtype;
 194
 195/* Module parameters */
 196static int recur_count = -1;
 197module_param(recur_count, int, 0644);
 198MODULE_PARM_DESC(recur_count, " Recursion level for the stack overflow test");
 199
 200static char* cpoint_name;
 201module_param(cpoint_name, charp, 0444);
 202MODULE_PARM_DESC(cpoint_name, " Crash Point, where kernel is to be crashed");
 203
 204static char* cpoint_type;
 205module_param(cpoint_type, charp, 0444);
 206MODULE_PARM_DESC(cpoint_type, " Crash Point Type, action to be taken on "\
 207                                "hitting the crash point");
 208
 209static int cpoint_count = DEFAULT_COUNT;
 210module_param(cpoint_count, int, 0644);
 211MODULE_PARM_DESC(cpoint_count, " Crash Point Count, number of times the "\
 212                                "crash point is to be hit to trigger action");
 213
 214/* For test debug reporting. */
 215char *lkdtm_kernel_info;
 216
 217/* Return the crashtype number or NULL if the name is invalid */
 218static const struct crashtype *find_crashtype(const char *name)
 219{
 220        int i;
 221
 222        for (i = 0; i < ARRAY_SIZE(crashtypes); i++) {
 223                if (!strcmp(name, crashtypes[i].name))
 224                        return &crashtypes[i];
 225        }
 226
 227        return NULL;
 228}
 229
 230/*
 231 * This is forced noinline just so it distinctly shows up in the stackdump
 232 * which makes validation of expected lkdtm crashes easier.
 233 */
 234static noinline void lkdtm_do_action(const struct crashtype *crashtype)
 235{
 236        if (WARN_ON(!crashtype || !crashtype->func))
 237                return;
 238        crashtype->func();
 239}
 240
 241static int lkdtm_register_cpoint(struct crashpoint *crashpoint,
 242                                 const struct crashtype *crashtype)
 243{
 244        int ret;
 245
 246        /* If this doesn't have a symbol, just call immediately. */
 247        if (!crashpoint->kprobe.symbol_name) {
 248                lkdtm_do_action(crashtype);
 249                return 0;
 250        }
 251
 252        if (lkdtm_kprobe != NULL)
 253                unregister_kprobe(lkdtm_kprobe);
 254
 255        lkdtm_crashpoint = crashpoint;
 256        lkdtm_crashtype = crashtype;
 257        lkdtm_kprobe = &crashpoint->kprobe;
 258        ret = register_kprobe(lkdtm_kprobe);
 259        if (ret < 0) {
 260                pr_info("Couldn't register kprobe %s\n",
 261                        crashpoint->kprobe.symbol_name);
 262                lkdtm_kprobe = NULL;
 263                lkdtm_crashpoint = NULL;
 264                lkdtm_crashtype = NULL;
 265        }
 266
 267        return ret;
 268}
 269
 270#ifdef CONFIG_KPROBES
 271/* Global crash counter and spinlock. */
 272static int crash_count = DEFAULT_COUNT;
 273static DEFINE_SPINLOCK(crash_count_lock);
 274
 275/* Called by kprobe entry points. */
 276static int lkdtm_kprobe_handler(struct kprobe *kp, struct pt_regs *regs)
 277{
 278        unsigned long flags;
 279        bool do_it = false;
 280
 281        if (WARN_ON(!lkdtm_crashpoint || !lkdtm_crashtype))
 282                return 0;
 283
 284        spin_lock_irqsave(&crash_count_lock, flags);
 285        crash_count--;
 286        pr_info("Crash point %s of type %s hit, trigger in %d rounds\n",
 287                lkdtm_crashpoint->name, lkdtm_crashtype->name, crash_count);
 288
 289        if (crash_count == 0) {
 290                do_it = true;
 291                crash_count = cpoint_count;
 292        }
 293        spin_unlock_irqrestore(&crash_count_lock, flags);
 294
 295        if (do_it)
 296                lkdtm_do_action(lkdtm_crashtype);
 297
 298        return 0;
 299}
 300
 301static ssize_t lkdtm_debugfs_entry(struct file *f,
 302                                   const char __user *user_buf,
 303                                   size_t count, loff_t *off)
 304{
 305        struct crashpoint *crashpoint = file_inode(f)->i_private;
 306        const struct crashtype *crashtype = NULL;
 307        char *buf;
 308        int err;
 309
 310        if (count >= PAGE_SIZE)
 311                return -EINVAL;
 312
 313        buf = (char *)__get_free_page(GFP_KERNEL);
 314        if (!buf)
 315                return -ENOMEM;
 316        if (copy_from_user(buf, user_buf, count)) {
 317                free_page((unsigned long) buf);
 318                return -EFAULT;
 319        }
 320        /* NULL-terminate and remove enter */
 321        buf[count] = '\0';
 322        strim(buf);
 323
 324        crashtype = find_crashtype(buf);
 325        free_page((unsigned long)buf);
 326
 327        if (!crashtype)
 328                return -EINVAL;
 329
 330        err = lkdtm_register_cpoint(crashpoint, crashtype);
 331        if (err < 0)
 332                return err;
 333
 334        *off += count;
 335
 336        return count;
 337}
 338#endif
 339
 340/* Generic read callback that just prints out the available crash types */
 341static ssize_t lkdtm_debugfs_read(struct file *f, char __user *user_buf,
 342                size_t count, loff_t *off)
 343{
 344        char *buf;
 345        int i, n, out;
 346
 347        buf = (char *)__get_free_page(GFP_KERNEL);
 348        if (buf == NULL)
 349                return -ENOMEM;
 350
 351        n = scnprintf(buf, PAGE_SIZE, "Available crash types:\n");
 352        for (i = 0; i < ARRAY_SIZE(crashtypes); i++) {
 353                n += scnprintf(buf + n, PAGE_SIZE - n, "%s\n",
 354                              crashtypes[i].name);
 355        }
 356        buf[n] = '\0';
 357
 358        out = simple_read_from_buffer(user_buf, count, off,
 359                                      buf, n);
 360        free_page((unsigned long) buf);
 361
 362        return out;
 363}
 364
 365static int lkdtm_debugfs_open(struct inode *inode, struct file *file)
 366{
 367        return 0;
 368}
 369
 370/* Special entry to just crash directly. Available without KPROBEs */
 371static ssize_t direct_entry(struct file *f, const char __user *user_buf,
 372                size_t count, loff_t *off)
 373{
 374        const struct crashtype *crashtype;
 375        char *buf;
 376
 377        if (count >= PAGE_SIZE)
 378                return -EINVAL;
 379        if (count < 1)
 380                return -EINVAL;
 381
 382        buf = (char *)__get_free_page(GFP_KERNEL);
 383        if (!buf)
 384                return -ENOMEM;
 385        if (copy_from_user(buf, user_buf, count)) {
 386                free_page((unsigned long) buf);
 387                return -EFAULT;
 388        }
 389        /* NULL-terminate and remove enter */
 390        buf[count] = '\0';
 391        strim(buf);
 392
 393        crashtype = find_crashtype(buf);
 394        free_page((unsigned long) buf);
 395        if (!crashtype)
 396                return -EINVAL;
 397
 398        pr_info("Performing direct entry %s\n", crashtype->name);
 399        lkdtm_do_action(crashtype);
 400        *off += count;
 401
 402        return count;
 403}
 404
 405#ifndef MODULE
 406/*
 407 * To avoid needing to export parse_args(), just don't use this code
 408 * when LKDTM is built as a module.
 409 */
 410struct check_cmdline_args {
 411        const char *param;
 412        int value;
 413};
 414
 415static int lkdtm_parse_one(char *param, char *val,
 416                           const char *unused, void *arg)
 417{
 418        struct check_cmdline_args *args = arg;
 419
 420        /* short circuit if we already found a value. */
 421        if (args->value != -ESRCH)
 422                return 0;
 423        if (strncmp(param, args->param, strlen(args->param)) == 0) {
 424                bool bool_result;
 425                int ret;
 426
 427                ret = kstrtobool(val, &bool_result);
 428                if (ret == 0)
 429                        args->value = bool_result;
 430        }
 431        return 0;
 432}
 433
 434int lkdtm_check_bool_cmdline(const char *param)
 435{
 436        char *command_line;
 437        struct check_cmdline_args args = {
 438                .param = param,
 439                .value = -ESRCH,
 440        };
 441
 442        command_line = kstrdup(saved_command_line, GFP_KERNEL);
 443        if (!command_line)
 444                return -ENOMEM;
 445
 446        parse_args("Setting sysctl args", command_line,
 447                   NULL, 0, -1, -1, &args, lkdtm_parse_one);
 448
 449        kfree(command_line);
 450
 451        return args.value;
 452}
 453#endif
 454
 455static struct dentry *lkdtm_debugfs_root;
 456
 457static int __init lkdtm_module_init(void)
 458{
 459        struct crashpoint *crashpoint = NULL;
 460        const struct crashtype *crashtype = NULL;
 461        int ret;
 462        int i;
 463
 464        /* Neither or both of these need to be set */
 465        if ((cpoint_type || cpoint_name) && !(cpoint_type && cpoint_name)) {
 466                pr_err("Need both cpoint_type and cpoint_name or neither\n");
 467                return -EINVAL;
 468        }
 469
 470        if (cpoint_type) {
 471                crashtype = find_crashtype(cpoint_type);
 472                if (!crashtype) {
 473                        pr_err("Unknown crashtype '%s'\n", cpoint_type);
 474                        return -EINVAL;
 475                }
 476        }
 477
 478        if (cpoint_name) {
 479                for (i = 0; i < ARRAY_SIZE(crashpoints); i++) {
 480                        if (!strcmp(cpoint_name, crashpoints[i].name))
 481                                crashpoint = &crashpoints[i];
 482                }
 483
 484                /* Refuse unknown crashpoints. */
 485                if (!crashpoint) {
 486                        pr_err("Invalid crashpoint %s\n", cpoint_name);
 487                        return -EINVAL;
 488                }
 489        }
 490
 491#ifdef CONFIG_KPROBES
 492        /* Set crash count. */
 493        crash_count = cpoint_count;
 494#endif
 495
 496        /* Common initialization. */
 497        lkdtm_kernel_info = kasprintf(GFP_KERNEL, "kernel (%s %s)",
 498                                      init_uts_ns.name.release,
 499                                      init_uts_ns.name.machine);
 500
 501        /* Handle test-specific initialization. */
 502        lkdtm_bugs_init(&recur_count);
 503        lkdtm_perms_init();
 504        lkdtm_usercopy_init();
 505        lkdtm_heap_init();
 506
 507        /* Register debugfs interface */
 508        lkdtm_debugfs_root = debugfs_create_dir("provoke-crash", NULL);
 509
 510        /* Install debugfs trigger files. */
 511        for (i = 0; i < ARRAY_SIZE(crashpoints); i++) {
 512                struct crashpoint *cur = &crashpoints[i];
 513
 514                debugfs_create_file(cur->name, 0644, lkdtm_debugfs_root, cur,
 515                                    &cur->fops);
 516        }
 517
 518        /* Install crashpoint if one was selected. */
 519        if (crashpoint) {
 520                ret = lkdtm_register_cpoint(crashpoint, crashtype);
 521                if (ret < 0) {
 522                        pr_info("Invalid crashpoint %s\n", crashpoint->name);
 523                        goto out_err;
 524                }
 525                pr_info("Crash point %s of type %s registered\n",
 526                        crashpoint->name, cpoint_type);
 527        } else {
 528                pr_info("No crash points registered, enable through debugfs\n");
 529        }
 530
 531        return 0;
 532
 533out_err:
 534        debugfs_remove_recursive(lkdtm_debugfs_root);
 535        return ret;
 536}
 537
 538static void __exit lkdtm_module_exit(void)
 539{
 540        debugfs_remove_recursive(lkdtm_debugfs_root);
 541
 542        /* Handle test-specific clean-up. */
 543        lkdtm_heap_exit();
 544        lkdtm_usercopy_exit();
 545
 546        if (lkdtm_kprobe != NULL)
 547                unregister_kprobe(lkdtm_kprobe);
 548
 549        kfree(lkdtm_kernel_info);
 550
 551        pr_info("Crash point unregistered\n");
 552}
 553
 554module_init(lkdtm_module_init);
 555module_exit(lkdtm_module_exit);
 556
 557MODULE_LICENSE("GPL");
 558MODULE_DESCRIPTION("Kernel crash testing module");
 559