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

helpers.c (2182B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Author: Aleksa Sarai <cyphar@cyphar.com>
      4 * Copyright (C) 2018-2019 SUSE LLC.
      5 */
      6
      7#define _GNU_SOURCE
      8#include <errno.h>
      9#include <fcntl.h>
     10#include <stdbool.h>
     11#include <string.h>
     12#include <syscall.h>
     13#include <limits.h>
     14
     15#include "helpers.h"
     16
     17bool needs_openat2(const struct open_how *how)
     18{
     19	return how->resolve != 0;
     20}
     21
     22int raw_openat2(int dfd, const char *path, void *how, size_t size)
     23{
     24	int ret = syscall(__NR_openat2, dfd, path, how, size);
     25	return ret >= 0 ? ret : -errno;
     26}
     27
     28int sys_openat2(int dfd, const char *path, struct open_how *how)
     29{
     30	return raw_openat2(dfd, path, how, sizeof(*how));
     31}
     32
     33int sys_openat(int dfd, const char *path, struct open_how *how)
     34{
     35	int ret = openat(dfd, path, how->flags, how->mode);
     36	return ret >= 0 ? ret : -errno;
     37}
     38
     39int sys_renameat2(int olddirfd, const char *oldpath,
     40		  int newdirfd, const char *newpath, unsigned int flags)
     41{
     42	int ret = syscall(__NR_renameat2, olddirfd, oldpath,
     43					  newdirfd, newpath, flags);
     44	return ret >= 0 ? ret : -errno;
     45}
     46
     47int touchat(int dfd, const char *path)
     48{
     49	int fd = openat(dfd, path, O_CREAT, 0700);
     50	if (fd >= 0)
     51		close(fd);
     52	return fd;
     53}
     54
     55char *fdreadlink(int fd)
     56{
     57	char *target, *tmp;
     58
     59	E_asprintf(&tmp, "/proc/self/fd/%d", fd);
     60
     61	target = malloc(PATH_MAX);
     62	if (!target)
     63		ksft_exit_fail_msg("fdreadlink: malloc failed\n");
     64	memset(target, 0, PATH_MAX);
     65
     66	E_readlink(tmp, target, PATH_MAX);
     67	free(tmp);
     68	return target;
     69}
     70
     71bool fdequal(int fd, int dfd, const char *path)
     72{
     73	char *fdpath, *dfdpath, *other;
     74	bool cmp;
     75
     76	fdpath = fdreadlink(fd);
     77	dfdpath = fdreadlink(dfd);
     78
     79	if (!path)
     80		E_asprintf(&other, "%s", dfdpath);
     81	else if (*path == '/')
     82		E_asprintf(&other, "%s", path);
     83	else
     84		E_asprintf(&other, "%s/%s", dfdpath, path);
     85
     86	cmp = !strcmp(fdpath, other);
     87
     88	free(fdpath);
     89	free(dfdpath);
     90	free(other);
     91	return cmp;
     92}
     93
     94bool openat2_supported = false;
     95
     96void __attribute__((constructor)) init(void)
     97{
     98	struct open_how how = {};
     99	int fd;
    100
    101	BUILD_BUG_ON(sizeof(struct open_how) != OPEN_HOW_SIZE_VER0);
    102
    103	/* Check openat2(2) support. */
    104	fd = sys_openat2(AT_FDCWD, ".", &how);
    105	openat2_supported = (fd >= 0);
    106
    107	if (fd >= 0)
    108		close(fd);
    109}