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