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

open-unlink.c (2252B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <errno.h>
      3#include <stdio.h>
      4#include <stdint.h>
      5#include <stdlib.h>
      6#include <unistd.h>
      7#include <sys/ioctl.h>
      8#include <sys/types.h>
      9#include <sys/stat.h>
     10#include <fcntl.h>
     11#include <linux/fs.h>
     12
     13static int set_immutable(const char *path, int immutable)
     14{
     15	unsigned int flags;
     16	int fd;
     17	int rc;
     18	int error;
     19
     20	fd = open(path, O_RDONLY);
     21	if (fd < 0)
     22		return fd;
     23
     24	rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
     25	if (rc < 0) {
     26		error = errno;
     27		close(fd);
     28		errno = error;
     29		return rc;
     30	}
     31
     32	if (immutable)
     33		flags |= FS_IMMUTABLE_FL;
     34	else
     35		flags &= ~FS_IMMUTABLE_FL;
     36
     37	rc = ioctl(fd, FS_IOC_SETFLAGS, &flags);
     38	error = errno;
     39	close(fd);
     40	errno = error;
     41	return rc;
     42}
     43
     44static int get_immutable(const char *path)
     45{
     46	unsigned int flags;
     47	int fd;
     48	int rc;
     49	int error;
     50
     51	fd = open(path, O_RDONLY);
     52	if (fd < 0)
     53		return fd;
     54
     55	rc = ioctl(fd, FS_IOC_GETFLAGS, &flags);
     56	if (rc < 0) {
     57		error = errno;
     58		close(fd);
     59		errno = error;
     60		return rc;
     61	}
     62	close(fd);
     63	if (flags & FS_IMMUTABLE_FL)
     64		return 1;
     65	return 0;
     66}
     67
     68int main(int argc, char **argv)
     69{
     70	const char *path;
     71	char buf[5];
     72	int fd, rc;
     73
     74	if (argc < 2) {
     75		fprintf(stderr, "usage: %s <path>\n", argv[0]);
     76		return EXIT_FAILURE;
     77	}
     78
     79	path = argv[1];
     80
     81	/* attributes: EFI_VARIABLE_NON_VOLATILE |
     82	 *		EFI_VARIABLE_BOOTSERVICE_ACCESS |
     83	 *		EFI_VARIABLE_RUNTIME_ACCESS
     84	 */
     85	*(uint32_t *)buf = 0x7;
     86	buf[4] = 0;
     87
     88	/* create a test variable */
     89	fd = open(path, O_WRONLY | O_CREAT, 0600);
     90	if (fd < 0) {
     91		perror("open(O_WRONLY)");
     92		return EXIT_FAILURE;
     93	}
     94
     95	rc = write(fd, buf, sizeof(buf));
     96	if (rc != sizeof(buf)) {
     97		perror("write");
     98		return EXIT_FAILURE;
     99	}
    100
    101	close(fd);
    102
    103	rc = get_immutable(path);
    104	if (rc < 0) {
    105		perror("ioctl(FS_IOC_GETFLAGS)");
    106		return EXIT_FAILURE;
    107	} else if (rc) {
    108		rc = set_immutable(path, 0);
    109		if (rc < 0) {
    110			perror("ioctl(FS_IOC_SETFLAGS)");
    111			return EXIT_FAILURE;
    112		}
    113	}
    114
    115	fd = open(path, O_RDONLY);
    116	if (fd < 0) {
    117		perror("open");
    118		return EXIT_FAILURE;
    119	}
    120
    121	if (unlink(path) < 0) {
    122		perror("unlink");
    123		return EXIT_FAILURE;
    124	}
    125
    126	rc = read(fd, buf, sizeof(buf));
    127	if (rc > 0) {
    128		fprintf(stderr, "reading from an unlinked variable "
    129				"shouldn't be possible\n");
    130		return EXIT_FAILURE;
    131	}
    132
    133	return EXIT_SUCCESS;
    134}