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);
}
Ejemplo n.º 2
0
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;
}