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

pty.c (3192B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
      4 */
      5
      6#include <stdio.h>
      7#include <stdlib.h>
      8#include <unistd.h>
      9#include <errno.h>
     10#include <fcntl.h>
     11#include <string.h>
     12#include <termios.h>
     13#include <sys/stat.h>
     14#include "chan_user.h"
     15#include <os.h>
     16#include <um_malloc.h>
     17
     18struct pty_chan {
     19	void (*announce)(char *dev_name, int dev);
     20	int dev;
     21	int raw;
     22	struct termios tt;
     23	char dev_name[sizeof("/dev/pts/0123456\0")];
     24};
     25
     26static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
     27{
     28	struct pty_chan *data;
     29
     30	data = uml_kmalloc(sizeof(*data), UM_GFP_KERNEL);
     31	if (data == NULL)
     32		return NULL;
     33
     34	*data = ((struct pty_chan) { .announce  	= opts->announce,
     35				     .dev  		= device,
     36				     .raw  		= opts->raw });
     37	return data;
     38}
     39
     40static int pts_open(int input, int output, int primary, void *d,
     41		    char **dev_out)
     42{
     43	struct pty_chan *data = d;
     44	char *dev;
     45	int fd, err;
     46
     47	fd = get_pty();
     48	if (fd < 0) {
     49		err = -errno;
     50		printk(UM_KERN_ERR "open_pts : Failed to open pts\n");
     51		return err;
     52	}
     53
     54	if (data->raw) {
     55		CATCH_EINTR(err = tcgetattr(fd, &data->tt));
     56		if (err)
     57			goto out_close;
     58
     59		err = raw(fd);
     60		if (err)
     61			goto out_close;
     62	}
     63
     64	dev = ptsname(fd);
     65	sprintf(data->dev_name, "%s", dev);
     66	*dev_out = data->dev_name;
     67
     68	if (data->announce)
     69		(*data->announce)(dev, data->dev);
     70
     71	return fd;
     72
     73out_close:
     74	close(fd);
     75	return err;
     76}
     77
     78static int getmaster(char *line)
     79{
     80	struct stat buf;
     81	char *pty, *bank, *cp;
     82	int master, err;
     83
     84	pty = &line[strlen("/dev/ptyp")];
     85	for (bank = "pqrs"; *bank; bank++) {
     86		line[strlen("/dev/pty")] = *bank;
     87		*pty = '0';
     88		/* Did we hit the end ? */
     89		if ((stat(line, &buf) < 0) && (errno == ENOENT))
     90			break;
     91
     92		for (cp = "0123456789abcdef"; *cp; cp++) {
     93			*pty = *cp;
     94			master = open(line, O_RDWR);
     95			if (master >= 0) {
     96				char *tp = &line[strlen("/dev/")];
     97
     98				/* verify slave side is usable */
     99				*tp = 't';
    100				err = access(line, R_OK | W_OK);
    101				*tp = 'p';
    102				if (!err)
    103					return master;
    104				close(master);
    105			}
    106		}
    107	}
    108
    109	printk(UM_KERN_ERR "getmaster - no usable host pty devices\n");
    110	return -ENOENT;
    111}
    112
    113static int pty_open(int input, int output, int primary, void *d,
    114		    char **dev_out)
    115{
    116	struct pty_chan *data = d;
    117	int fd, err;
    118	char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx";
    119
    120	fd = getmaster(dev);
    121	if (fd < 0)
    122		return fd;
    123
    124	if (data->raw) {
    125		err = raw(fd);
    126		if (err) {
    127			close(fd);
    128			return err;
    129		}
    130	}
    131
    132	if (data->announce)
    133		(*data->announce)(dev, data->dev);
    134
    135	sprintf(data->dev_name, "%s", dev);
    136	*dev_out = data->dev_name;
    137
    138	return fd;
    139}
    140
    141const struct chan_ops pty_ops = {
    142	.type		= "pty",
    143	.init		= pty_chan_init,
    144	.open		= pty_open,
    145	.close		= generic_close,
    146	.read		= generic_read,
    147	.write		= generic_write,
    148	.console_write	= generic_console_write,
    149	.window_size	= generic_window_size,
    150	.free		= generic_free,
    151	.winch		= 0,
    152};
    153
    154const struct chan_ops pts_ops = {
    155	.type		= "pts",
    156	.init		= pty_chan_init,
    157	.open		= pts_open,
    158	.close		= generic_close,
    159	.read		= generic_read,
    160	.write		= generic_write,
    161	.console_write	= generic_console_write,
    162	.window_size	= generic_window_size,
    163	.free		= generic_free,
    164	.winch		= 0,
    165};