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

file.c (12961B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
      4 */
      5
      6#include <stdio.h>
      7#include <unistd.h>
      8#include <stdlib.h>
      9#include <string.h>
     10#include <errno.h>
     11#include <fcntl.h>
     12#include <signal.h>
     13#include <linux/falloc.h>
     14#include <sys/ioctl.h>
     15#include <sys/mount.h>
     16#include <sys/socket.h>
     17#include <sys/stat.h>
     18#include <sys/sysmacros.h>
     19#include <sys/un.h>
     20#include <sys/types.h>
     21#include <sys/eventfd.h>
     22#include <poll.h>
     23#include <os.h>
     24
     25static void copy_stat(struct uml_stat *dst, const struct stat64 *src)
     26{
     27	*dst = ((struct uml_stat) {
     28		.ust_dev     = src->st_dev,     /* device */
     29		.ust_ino     = src->st_ino,     /* inode */
     30		.ust_mode    = src->st_mode,    /* protection */
     31		.ust_nlink   = src->st_nlink,   /* number of hard links */
     32		.ust_uid     = src->st_uid,     /* user ID of owner */
     33		.ust_gid     = src->st_gid,     /* group ID of owner */
     34		.ust_size    = src->st_size,    /* total size, in bytes */
     35		.ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
     36		.ust_blocks  = src->st_blocks,  /* number of blocks allocated */
     37		.ust_atime   = src->st_atime,   /* time of last access */
     38		.ust_mtime   = src->st_mtime,   /* time of last modification */
     39		.ust_ctime   = src->st_ctime,   /* time of last change */
     40	});
     41}
     42
     43int os_stat_fd(const int fd, struct uml_stat *ubuf)
     44{
     45	struct stat64 sbuf;
     46	int err;
     47
     48	CATCH_EINTR(err = fstat64(fd, &sbuf));
     49	if (err < 0)
     50		return -errno;
     51
     52	if (ubuf != NULL)
     53		copy_stat(ubuf, &sbuf);
     54	return err;
     55}
     56
     57int os_stat_file(const char *file_name, struct uml_stat *ubuf)
     58{
     59	struct stat64 sbuf;
     60	int err;
     61
     62	CATCH_EINTR(err = stat64(file_name, &sbuf));
     63	if (err < 0)
     64		return -errno;
     65
     66	if (ubuf != NULL)
     67		copy_stat(ubuf, &sbuf);
     68	return err;
     69}
     70
     71int os_access(const char *file, int mode)
     72{
     73	int amode, err;
     74
     75	amode = (mode & OS_ACC_R_OK ? R_OK : 0) |
     76		(mode & OS_ACC_W_OK ? W_OK : 0) |
     77		(mode & OS_ACC_X_OK ? X_OK : 0) |
     78		(mode & OS_ACC_F_OK ? F_OK : 0);
     79
     80	err = access(file, amode);
     81	if (err < 0)
     82		return -errno;
     83
     84	return 0;
     85}
     86
     87/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
     88int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
     89{
     90	int err;
     91
     92	err = ioctl(fd, cmd, arg);
     93	if (err < 0)
     94		return -errno;
     95
     96	return err;
     97}
     98
     99/* FIXME: ensure namebuf in os_get_if_name is big enough */
    100int os_get_ifname(int fd, char* namebuf)
    101{
    102	if (ioctl(fd, SIOCGIFNAME, namebuf) < 0)
    103		return -errno;
    104
    105	return 0;
    106}
    107
    108int os_set_slip(int fd)
    109{
    110	int disc, sencap;
    111
    112	disc = N_SLIP;
    113	if (ioctl(fd, TIOCSETD, &disc) < 0)
    114		return -errno;
    115
    116	sencap = 0;
    117	if (ioctl(fd, SIOCSIFENCAP, &sencap) < 0)
    118		return -errno;
    119
    120	return 0;
    121}
    122
    123int os_mode_fd(int fd, int mode)
    124{
    125	int err;
    126
    127	CATCH_EINTR(err = fchmod(fd, mode));
    128	if (err < 0)
    129		return -errno;
    130
    131	return 0;
    132}
    133
    134int os_file_type(char *file)
    135{
    136	struct uml_stat buf;
    137	int err;
    138
    139	err = os_stat_file(file, &buf);
    140	if (err < 0)
    141		return err;
    142
    143	if (S_ISDIR(buf.ust_mode))
    144		return OS_TYPE_DIR;
    145	else if (S_ISLNK(buf.ust_mode))
    146		return OS_TYPE_SYMLINK;
    147	else if (S_ISCHR(buf.ust_mode))
    148		return OS_TYPE_CHARDEV;
    149	else if (S_ISBLK(buf.ust_mode))
    150		return OS_TYPE_BLOCKDEV;
    151	else if (S_ISFIFO(buf.ust_mode))
    152		return OS_TYPE_FIFO;
    153	else if (S_ISSOCK(buf.ust_mode))
    154		return OS_TYPE_SOCK;
    155	else return OS_TYPE_FILE;
    156}
    157
    158int os_file_mode(const char *file, struct openflags *mode_out)
    159{
    160	int err;
    161
    162	*mode_out = OPENFLAGS();
    163
    164	err = access(file, W_OK);
    165	if (err && (errno != EACCES))
    166		return -errno;
    167	else if (!err)
    168		*mode_out = of_write(*mode_out);
    169
    170	err = access(file, R_OK);
    171	if (err && (errno != EACCES))
    172		return -errno;
    173	else if (!err)
    174		*mode_out = of_read(*mode_out);
    175
    176	return err;
    177}
    178
    179int os_open_file(const char *file, struct openflags flags, int mode)
    180{
    181	int fd, err, f = 0;
    182
    183	if (flags.r && flags.w)
    184		f = O_RDWR;
    185	else if (flags.r)
    186		f = O_RDONLY;
    187	else if (flags.w)
    188		f = O_WRONLY;
    189	else f = 0;
    190
    191	if (flags.s)
    192		f |= O_SYNC;
    193	if (flags.c)
    194		f |= O_CREAT;
    195	if (flags.t)
    196		f |= O_TRUNC;
    197	if (flags.e)
    198		f |= O_EXCL;
    199	if (flags.a)
    200		f |= O_APPEND;
    201
    202	fd = open64(file, f, mode);
    203	if (fd < 0)
    204		return -errno;
    205
    206	if (flags.cl && fcntl(fd, F_SETFD, 1)) {
    207		err = -errno;
    208		close(fd);
    209		return err;
    210	}
    211
    212	return fd;
    213}
    214
    215int os_connect_socket(const char *name)
    216{
    217	struct sockaddr_un sock;
    218	int fd, err;
    219
    220	sock.sun_family = AF_UNIX;
    221	snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name);
    222
    223	fd = socket(AF_UNIX, SOCK_STREAM, 0);
    224	if (fd < 0) {
    225		err = -errno;
    226		goto out;
    227	}
    228
    229	err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
    230	if (err) {
    231		err = -errno;
    232		goto out_close;
    233	}
    234
    235	return fd;
    236
    237out_close:
    238	close(fd);
    239out:
    240	return err;
    241}
    242
    243void os_close_file(int fd)
    244{
    245	close(fd);
    246}
    247int os_fsync_file(int fd)
    248{
    249	if (fsync(fd) < 0)
    250	    return -errno;
    251	return 0;
    252}
    253
    254int os_seek_file(int fd, unsigned long long offset)
    255{
    256	unsigned long long actual;
    257
    258	actual = lseek64(fd, offset, SEEK_SET);
    259	if (actual != offset)
    260		return -errno;
    261	return 0;
    262}
    263
    264int os_read_file(int fd, void *buf, int len)
    265{
    266	int n = read(fd, buf, len);
    267
    268	if (n < 0)
    269		return -errno;
    270	return n;
    271}
    272
    273int os_pread_file(int fd, void *buf, int len, unsigned long long offset)
    274{
    275	int n = pread(fd, buf, len, offset);
    276
    277	if (n < 0)
    278		return -errno;
    279	return n;
    280}
    281
    282int os_write_file(int fd, const void *buf, int len)
    283{
    284	int n = write(fd, (void *) buf, len);
    285
    286	if (n < 0)
    287		return -errno;
    288	return n;
    289}
    290
    291int os_sync_file(int fd)
    292{
    293	int n = fdatasync(fd);
    294
    295	if (n < 0)
    296		return -errno;
    297	return n;
    298}
    299
    300int os_pwrite_file(int fd, const void *buf, int len, unsigned long long offset)
    301{
    302	int n = pwrite(fd, (void *) buf, len, offset);
    303
    304	if (n < 0)
    305		return -errno;
    306	return n;
    307}
    308
    309
    310int os_file_size(const char *file, unsigned long long *size_out)
    311{
    312	struct uml_stat buf;
    313	int err;
    314
    315	err = os_stat_file(file, &buf);
    316	if (err < 0) {
    317		printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
    318		       -err);
    319		return err;
    320	}
    321
    322	if (S_ISBLK(buf.ust_mode)) {
    323		int fd;
    324		long blocks;
    325
    326		fd = open(file, O_RDONLY, 0);
    327		if (fd < 0) {
    328			err = -errno;
    329			printk(UM_KERN_ERR "Couldn't open \"%s\", "
    330			       "errno = %d\n", file, errno);
    331			return err;
    332		}
    333		if (ioctl(fd, BLKGETSIZE, &blocks) < 0) {
    334			err = -errno;
    335			printk(UM_KERN_ERR "Couldn't get the block size of "
    336			       "\"%s\", errno = %d\n", file, errno);
    337			close(fd);
    338			return err;
    339		}
    340		*size_out = ((long long) blocks) * 512;
    341		close(fd);
    342	}
    343	else *size_out = buf.ust_size;
    344
    345	return 0;
    346}
    347
    348int os_file_modtime(const char *file, long long *modtime)
    349{
    350	struct uml_stat buf;
    351	int err;
    352
    353	err = os_stat_file(file, &buf);
    354	if (err < 0) {
    355		printk(UM_KERN_ERR "Couldn't stat \"%s\" : err = %d\n", file,
    356		       -err);
    357		return err;
    358	}
    359
    360	*modtime = buf.ust_mtime;
    361	return 0;
    362}
    363
    364int os_set_exec_close(int fd)
    365{
    366	int err;
    367
    368	CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC));
    369
    370	if (err < 0)
    371		return -errno;
    372	return err;
    373}
    374
    375int os_pipe(int *fds, int stream, int close_on_exec)
    376{
    377	int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
    378
    379	err = socketpair(AF_UNIX, type, 0, fds);
    380	if (err < 0)
    381		return -errno;
    382
    383	if (!close_on_exec)
    384		return 0;
    385
    386	err = os_set_exec_close(fds[0]);
    387	if (err < 0)
    388		goto error;
    389
    390	err = os_set_exec_close(fds[1]);
    391	if (err < 0)
    392		goto error;
    393
    394	return 0;
    395
    396 error:
    397	printk(UM_KERN_ERR "os_pipe : Setting FD_CLOEXEC failed, err = %d\n",
    398	       -err);
    399	close(fds[1]);
    400	close(fds[0]);
    401	return err;
    402}
    403
    404int os_set_fd_async(int fd)
    405{
    406	int err, flags;
    407
    408	flags = fcntl(fd, F_GETFL);
    409	if (flags < 0)
    410		return -errno;
    411
    412	flags |= O_ASYNC | O_NONBLOCK;
    413	if (fcntl(fd, F_SETFL, flags) < 0) {
    414		err = -errno;
    415		printk(UM_KERN_ERR "os_set_fd_async : failed to set O_ASYNC "
    416		       "and O_NONBLOCK on fd # %d, errno = %d\n", fd, errno);
    417		return err;
    418	}
    419
    420	if ((fcntl(fd, F_SETSIG, SIGIO) < 0) ||
    421	    (fcntl(fd, F_SETOWN, os_getpid()) < 0)) {
    422		err = -errno;
    423		printk(UM_KERN_ERR "os_set_fd_async : Failed to fcntl F_SETOWN "
    424		       "(or F_SETSIG) fd %d, errno = %d\n", fd, errno);
    425		return err;
    426	}
    427
    428	return 0;
    429}
    430
    431int os_clear_fd_async(int fd)
    432{
    433	int flags;
    434
    435	flags = fcntl(fd, F_GETFL);
    436	if (flags < 0)
    437		return -errno;
    438
    439	flags &= ~(O_ASYNC | O_NONBLOCK);
    440	if (fcntl(fd, F_SETFL, flags) < 0)
    441		return -errno;
    442	return 0;
    443}
    444
    445int os_set_fd_block(int fd, int blocking)
    446{
    447	int flags;
    448
    449	flags = fcntl(fd, F_GETFL);
    450	if (flags < 0)
    451		return -errno;
    452
    453	if (blocking)
    454		flags &= ~O_NONBLOCK;
    455	else
    456		flags |= O_NONBLOCK;
    457
    458	if (fcntl(fd, F_SETFL, flags) < 0)
    459		return -errno;
    460
    461	return 0;
    462}
    463
    464int os_accept_connection(int fd)
    465{
    466	int new;
    467
    468	new = accept(fd, NULL, 0);
    469	if (new < 0)
    470		return -errno;
    471	return new;
    472}
    473
    474#ifndef SHUT_RD
    475#define SHUT_RD 0
    476#endif
    477
    478#ifndef SHUT_WR
    479#define SHUT_WR 1
    480#endif
    481
    482#ifndef SHUT_RDWR
    483#define SHUT_RDWR 2
    484#endif
    485
    486int os_shutdown_socket(int fd, int r, int w)
    487{
    488	int what, err;
    489
    490	if (r && w)
    491		what = SHUT_RDWR;
    492	else if (r)
    493		what = SHUT_RD;
    494	else if (w)
    495		what = SHUT_WR;
    496	else
    497		return -EINVAL;
    498
    499	err = shutdown(fd, what);
    500	if (err < 0)
    501		return -errno;
    502	return 0;
    503}
    504
    505int os_rcv_fd(int fd, int *helper_pid_out)
    506{
    507	int new, n;
    508	char buf[CMSG_SPACE(sizeof(new))];
    509	struct msghdr msg;
    510	struct cmsghdr *cmsg;
    511	struct iovec iov;
    512
    513	msg.msg_name = NULL;
    514	msg.msg_namelen = 0;
    515	iov = ((struct iovec) { .iov_base  = helper_pid_out,
    516				.iov_len   = sizeof(*helper_pid_out) });
    517	msg.msg_iov = &iov;
    518	msg.msg_iovlen = 1;
    519	msg.msg_control = buf;
    520	msg.msg_controllen = sizeof(buf);
    521	msg.msg_flags = 0;
    522
    523	n = recvmsg(fd, &msg, 0);
    524	if (n < 0)
    525		return -errno;
    526	else if (n != iov.iov_len)
    527		*helper_pid_out = -1;
    528
    529	cmsg = CMSG_FIRSTHDR(&msg);
    530	if (cmsg == NULL) {
    531		printk(UM_KERN_ERR "rcv_fd didn't receive anything, "
    532		       "error = %d\n", errno);
    533		return -1;
    534	}
    535	if ((cmsg->cmsg_level != SOL_SOCKET) ||
    536	    (cmsg->cmsg_type != SCM_RIGHTS)) {
    537		printk(UM_KERN_ERR "rcv_fd didn't receive a descriptor\n");
    538		return -1;
    539	}
    540
    541	new = ((int *) CMSG_DATA(cmsg))[0];
    542	return new;
    543}
    544
    545int os_create_unix_socket(const char *file, int len, int close_on_exec)
    546{
    547	struct sockaddr_un addr;
    548	int sock, err;
    549
    550	sock = socket(PF_UNIX, SOCK_DGRAM, 0);
    551	if (sock < 0)
    552		return -errno;
    553
    554	if (close_on_exec) {
    555		err = os_set_exec_close(sock);
    556		if (err < 0)
    557			printk(UM_KERN_ERR "create_unix_socket : "
    558			       "close_on_exec failed, err = %d", -err);
    559	}
    560
    561	addr.sun_family = AF_UNIX;
    562
    563	snprintf(addr.sun_path, len, "%s", file);
    564
    565	err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
    566	if (err < 0)
    567		return -errno;
    568
    569	return sock;
    570}
    571
    572void os_flush_stdout(void)
    573{
    574	fflush(stdout);
    575}
    576
    577int os_lock_file(int fd, int excl)
    578{
    579	int type = excl ? F_WRLCK : F_RDLCK;
    580	struct flock lock = ((struct flock) { .l_type	= type,
    581					      .l_whence	= SEEK_SET,
    582					      .l_start	= 0,
    583					      .l_len	= 0 } );
    584	int err, save;
    585
    586	err = fcntl(fd, F_SETLK, &lock);
    587	if (!err)
    588		goto out;
    589
    590	save = -errno;
    591	err = fcntl(fd, F_GETLK, &lock);
    592	if (err) {
    593		err = -errno;
    594		goto out;
    595	}
    596
    597	printk(UM_KERN_ERR "F_SETLK failed, file already locked by pid %d\n",
    598	       lock.l_pid);
    599	err = save;
    600 out:
    601	return err;
    602}
    603
    604unsigned os_major(unsigned long long dev)
    605{
    606	return major(dev);
    607}
    608
    609unsigned os_minor(unsigned long long dev)
    610{
    611	return minor(dev);
    612}
    613
    614unsigned long long os_makedev(unsigned major, unsigned minor)
    615{
    616	return makedev(major, minor);
    617}
    618
    619int os_falloc_punch(int fd, unsigned long long offset, int len)
    620{
    621	int n = fallocate(fd, FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE, offset, len);
    622
    623	if (n < 0)
    624		return -errno;
    625	return n;
    626}
    627
    628int os_falloc_zeroes(int fd, unsigned long long offset, int len)
    629{
    630	int n = fallocate(fd, FALLOC_FL_ZERO_RANGE|FALLOC_FL_KEEP_SIZE, offset, len);
    631
    632	if (n < 0)
    633		return -errno;
    634	return n;
    635}
    636
    637int os_eventfd(unsigned int initval, int flags)
    638{
    639	int fd = eventfd(initval, flags);
    640
    641	if (fd < 0)
    642		return -errno;
    643	return fd;
    644}
    645
    646int os_sendmsg_fds(int fd, const void *buf, unsigned int len, const int *fds,
    647		   unsigned int fds_num)
    648{
    649	struct iovec iov = {
    650		.iov_base = (void *) buf,
    651		.iov_len = len,
    652	};
    653	union {
    654		char control[CMSG_SPACE(sizeof(*fds) * OS_SENDMSG_MAX_FDS)];
    655		struct cmsghdr align;
    656	} u;
    657	unsigned int fds_size = sizeof(*fds) * fds_num;
    658	struct msghdr msg = {
    659		.msg_iov = &iov,
    660		.msg_iovlen = 1,
    661		.msg_control = u.control,
    662		.msg_controllen = CMSG_SPACE(fds_size),
    663	};
    664	struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
    665	int err;
    666
    667	if (fds_num > OS_SENDMSG_MAX_FDS)
    668		return -EINVAL;
    669	memset(u.control, 0, sizeof(u.control));
    670	cmsg->cmsg_level = SOL_SOCKET;
    671	cmsg->cmsg_type = SCM_RIGHTS;
    672	cmsg->cmsg_len = CMSG_LEN(fds_size);
    673	memcpy(CMSG_DATA(cmsg), fds, fds_size);
    674	err = sendmsg(fd, &msg, 0);
    675
    676	if (err < 0)
    677		return -errno;
    678	return err;
    679}
    680
    681int os_poll(unsigned int n, const int *fds)
    682{
    683	/* currently need 2 FDs at most so avoid dynamic allocation */
    684	struct pollfd pollfds[2] = {};
    685	unsigned int i;
    686	int ret;
    687
    688	if (n > ARRAY_SIZE(pollfds))
    689		return -EINVAL;
    690
    691	for (i = 0; i < n; i++) {
    692		pollfds[i].fd = fds[i];
    693		pollfds[i].events = POLLIN;
    694	}
    695
    696	ret = poll(pollfds, n, -1);
    697	if (ret < 0)
    698		return -errno;
    699
    700	/* Return the index of the available FD */
    701	for (i = 0; i < n; i++) {
    702		if (pollfds[i].revents)
    703			return i;
    704	}
    705
    706	return -EIO;
    707}