static void chromeos_invalidate_kernel_endio(struct bio *bio, int err) { const char *mode = ((bio->bi_rw & REQ_WRITE) ? "write" : "read"); if (err) chromeos_set_need_recovery(); if (bio_flagged(bio, BIO_EOPNOTSUPP)) { DMERR("invalidate_kernel: %s not supported", mode); chromeos_set_need_recovery(); } else if (!bio_flagged(bio, BIO_UPTODATE)) { DMERR("invalidate_kernel: %s not up to date", mode); chromeos_set_need_recovery(); } else { DMERR("invalidate_kernel: partition header %s completed", mode); } complete(bio->bi_private); }
static ssize_t write_breakme(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { char kbuf[MAX_BREAKME_WRITE + 1]; DEFINE_SPINLOCK(lock_me_up); if (count) { if (count > MAX_BREAKME_WRITE) return -EINVAL; if (copy_from_user(&kbuf, buf, count)) return -EFAULT; kbuf[min(count, sizeof(kbuf))-1] = '\0'; /* Null pointer dereference */ if (!strcmp(kbuf, "nullptr")) *(unsigned long *)0 = 0; /* BUG() */ else if (!strcmp(kbuf, "bug")) BUG(); /* hung_task stuck in unkillable D state */ else if (!strcmp(kbuf, "hungtask")) schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT); /* Panic */ else if (!strcmp(kbuf, "panic")) panic("Testing panic"); /* Set up a deadlock (call this twice) */ else if (!strcmp(kbuf, "deadlock")) spin_lock(&lock_me_up); /* lockup */ else if (!strcmp(kbuf, "softlockup")) { while (1) ; } /* lockup with interrupts enabled */ else if (!strcmp(kbuf, "irqlockup")) { spin_lock(&lock_me_up); while (1) ; } /* lockup with interrupts disabled */ else if (!strcmp(kbuf, "nmiwatchdog")) { spin_lock_irq(&lock_me_up); while (1) ; } else if (!strcmp(kbuf, "need_recovery")) chromeos_set_need_recovery(); } return count; }
static int error_handler(struct notifier_block *nb, unsigned long transient, void *opaque_err) { struct dm_verity_error_state *err = (struct dm_verity_error_state *) opaque_err; err->behavior = DM_VERITY_ERROR_BEHAVIOR_PANIC; if (transient) return 0; /* TODO(wad) Implement phase 2: * - Attempt to read the dev_status_offset from the hash dev. * - If the status offset is 0, replace the first byte of the sector * with 01 and panic(). * - If the status offset is not 0, invalidate the associated kernel * partition, then reboot. * - make user space tools clear the last sector */ if (chromeos_invalidate_kernel(err->dev)) chromeos_set_need_recovery(); return 0; }