cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ctrlchar.c (1795B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 *  Unified handling of special chars.
      4 *
      5 *    Copyright IBM Corp. 2001
      6 *    Author(s): Fritz Elfert <felfert@millenux.com> <elfert@de.ibm.com>
      7 *
      8 */
      9
     10#include <linux/stddef.h>
     11#include <asm/errno.h>
     12#include <linux/sysrq.h>
     13#include <linux/ctype.h>
     14
     15#include "ctrlchar.h"
     16
     17#ifdef CONFIG_MAGIC_SYSRQ
     18static struct sysrq_work ctrlchar_sysrq;
     19
     20static void
     21ctrlchar_handle_sysrq(struct work_struct *work)
     22{
     23	struct sysrq_work *sysrq = container_of(work, struct sysrq_work, work);
     24
     25	handle_sysrq(sysrq->key);
     26}
     27
     28void schedule_sysrq_work(struct sysrq_work *sw)
     29{
     30	INIT_WORK(&sw->work, ctrlchar_handle_sysrq);
     31	schedule_work(&sw->work);
     32}
     33#endif
     34
     35
     36/**
     37 * ctrlchar_handle - check for special chars at start of input
     38 *
     39 * @buf: console input buffer
     40 * @len: length of valid data in buffer
     41 * @tty: the tty struct for this console
     42 *
     43 * Return: CTRLCHAR_NONE, if nothing matched,
     44 *         CTRLCHAR_SYSRQ, if sysrq was encountered
     45 *         otherwise char to be inserted logically or'ed
     46 *         with CTRLCHAR_CTRL
     47 */
     48unsigned int
     49ctrlchar_handle(const unsigned char *buf, int len, struct tty_struct *tty)
     50{
     51	if ((len < 2) || (len > 3))
     52		return CTRLCHAR_NONE;
     53
     54	/* hat is 0xb1 in codepage 037 (US etc.) and thus */
     55	/* converted to 0x5e in ascii ('^') */
     56	if ((buf[0] != '^') && (buf[0] != '\252'))
     57		return CTRLCHAR_NONE;
     58
     59#ifdef CONFIG_MAGIC_SYSRQ
     60	/* racy */
     61	if (len == 3 && buf[1] == '-') {
     62		ctrlchar_sysrq.key = buf[2];
     63		schedule_sysrq_work(&ctrlchar_sysrq);
     64		return CTRLCHAR_SYSRQ;
     65	}
     66#endif
     67
     68	if (len != 2)
     69		return CTRLCHAR_NONE;
     70
     71	switch (tolower(buf[1])) {
     72	case 'c':
     73		return INTR_CHAR(tty) | CTRLCHAR_CTRL;
     74	case 'd':
     75		return EOF_CHAR(tty)  | CTRLCHAR_CTRL;
     76	case 'z':
     77		return SUSP_CHAR(tty) | CTRLCHAR_CTRL;
     78	}
     79	return CTRLCHAR_NONE;
     80}