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

slip_user.c (5098B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 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/wait.h>
     14#include <net_user.h>
     15#include <os.h>
     16#include "slip.h"
     17#include <um_malloc.h>
     18
     19static int slip_user_init(void *data, void *dev)
     20{
     21	struct slip_data *pri = data;
     22
     23	pri->dev = dev;
     24	return 0;
     25}
     26
     27static int set_up_tty(int fd)
     28{
     29	int i;
     30	struct termios tios;
     31
     32	if (tcgetattr(fd, &tios) < 0) {
     33		printk(UM_KERN_ERR "could not get initial terminal "
     34		       "attributes\n");
     35		return -1;
     36	}
     37
     38	tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
     39	tios.c_iflag = IGNBRK | IGNPAR;
     40	tios.c_oflag = 0;
     41	tios.c_lflag = 0;
     42	for (i = 0; i < NCCS; i++)
     43		tios.c_cc[i] = 0;
     44	tios.c_cc[VMIN] = 1;
     45	tios.c_cc[VTIME] = 0;
     46
     47	cfsetospeed(&tios, B38400);
     48	cfsetispeed(&tios, B38400);
     49
     50	if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
     51		printk(UM_KERN_ERR "failed to set terminal attributes\n");
     52		return -1;
     53	}
     54	return 0;
     55}
     56
     57struct slip_pre_exec_data {
     58	int stdin_fd;
     59	int stdout_fd;
     60	int close_me;
     61};
     62
     63static void slip_pre_exec(void *arg)
     64{
     65	struct slip_pre_exec_data *data = arg;
     66
     67	if (data->stdin_fd >= 0)
     68		dup2(data->stdin_fd, 0);
     69	dup2(data->stdout_fd, 1);
     70	if (data->close_me >= 0)
     71		close(data->close_me);
     72}
     73
     74static int slip_tramp(char **argv, int fd)
     75{
     76	struct slip_pre_exec_data pe_data;
     77	char *output;
     78	int pid, fds[2], err, output_len;
     79
     80	err = os_pipe(fds, 1, 0);
     81	if (err < 0) {
     82		printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
     83		       -err);
     84		goto out;
     85	}
     86
     87	err = 0;
     88	pe_data.stdin_fd = fd;
     89	pe_data.stdout_fd = fds[1];
     90	pe_data.close_me = fds[0];
     91	err = run_helper(slip_pre_exec, &pe_data, argv);
     92	if (err < 0)
     93		goto out_close;
     94	pid = err;
     95
     96	output_len = UM_KERN_PAGE_SIZE;
     97	output = uml_kmalloc(output_len, UM_GFP_KERNEL);
     98	if (output == NULL) {
     99		printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
    100		       "buffer\n");
    101		os_kill_process(pid, 1);
    102		err = -ENOMEM;
    103		goto out_close;
    104	}
    105
    106	close(fds[1]);
    107	read_output(fds[0], output, output_len);
    108	printk("%s", output);
    109
    110	err = helper_wait(pid);
    111	close(fds[0]);
    112
    113	kfree(output);
    114	return err;
    115
    116out_close:
    117	close(fds[0]);
    118	close(fds[1]);
    119out:
    120	return err;
    121}
    122
    123static int slip_open(void *data)
    124{
    125	struct slip_data *pri = data;
    126	char version_buf[sizeof("nnnnn\0")];
    127	char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
    128	char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
    129			 NULL };
    130	int sfd, mfd, err;
    131
    132	err = get_pty();
    133	if (err < 0) {
    134		printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n",
    135		       -err);
    136		goto out;
    137	}
    138	mfd = err;
    139
    140	err = open(ptsname(mfd), O_RDWR, 0);
    141	if (err < 0) {
    142		printk(UM_KERN_ERR "Couldn't open tty for slip line, "
    143		       "err = %d\n", -err);
    144		goto out_close;
    145	}
    146	sfd = err;
    147
    148	err = set_up_tty(sfd);
    149	if (err)
    150		goto out_close2;
    151
    152	pri->slave = sfd;
    153	pri->slip.pos = 0;
    154	pri->slip.esc = 0;
    155	if (pri->gate_addr != NULL) {
    156		sprintf(version_buf, "%d", UML_NET_VERSION);
    157		strcpy(gate_buf, pri->gate_addr);
    158
    159		err = slip_tramp(argv, sfd);
    160
    161		if (err < 0) {
    162			printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
    163			       -err);
    164			goto out_close2;
    165		}
    166		err = os_get_ifname(pri->slave, pri->name);
    167		if (err < 0) {
    168			printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
    169			       -err);
    170			goto out_close2;
    171		}
    172		iter_addresses(pri->dev, open_addr, pri->name);
    173	}
    174	else {
    175		err = os_set_slip(sfd);
    176		if (err < 0) {
    177			printk(UM_KERN_ERR "Failed to set slip discipline "
    178			       "encapsulation - err = %d\n", -err);
    179			goto out_close2;
    180		}
    181	}
    182	return mfd;
    183out_close2:
    184	close(sfd);
    185out_close:
    186	close(mfd);
    187out:
    188	return err;
    189}
    190
    191static void slip_close(int fd, void *data)
    192{
    193	struct slip_data *pri = data;
    194	char version_buf[sizeof("nnnnn\0")];
    195	char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
    196			 NULL };
    197	int err;
    198
    199	if (pri->gate_addr != NULL)
    200		iter_addresses(pri->dev, close_addr, pri->name);
    201
    202	sprintf(version_buf, "%d", UML_NET_VERSION);
    203
    204	err = slip_tramp(argv, pri->slave);
    205
    206	if (err != 0)
    207		printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
    208	close(fd);
    209	close(pri->slave);
    210	pri->slave = -1;
    211}
    212
    213int slip_user_read(int fd, void *buf, int len, struct slip_data *pri)
    214{
    215	return slip_proto_read(fd, buf, len, &pri->slip);
    216}
    217
    218int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
    219{
    220	return slip_proto_write(fd, buf, len, &pri->slip);
    221}
    222
    223static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
    224			  void *data)
    225{
    226	struct slip_data *pri = data;
    227
    228	if (pri->slave < 0)
    229		return;
    230	open_addr(addr, netmask, pri->name);
    231}
    232
    233static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
    234			    void *data)
    235{
    236	struct slip_data *pri = data;
    237
    238	if (pri->slave < 0)
    239		return;
    240	close_addr(addr, netmask, pri->name);
    241}
    242
    243const struct net_user_info slip_user_info = {
    244	.init		= slip_user_init,
    245	.open		= slip_open,
    246	.close	 	= slip_close,
    247	.remove	 	= NULL,
    248	.add_address	= slip_add_addr,
    249	.delete_address = slip_del_addr,
    250	.mtu		= BUF_SIZE,
    251	.max_packet	= BUF_SIZE,
    252};