brintos

brintos / linux-shallow public Read only

0
0
Text · 2.2 KiB · 562742d Raw
135 lines · c
1// SPDX-License-Identifier: GPL-2.02#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	else35		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_ACCESS84	 */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}135