xref: /aosp_15_r20/external/selinux/libselinux/src/fsetfilecon.c (revision 2d543d20722ada2425b5bdab9d0d1d29470e7bba)
1*2d543d20SAndroid Build Coastguard Worker #include <unistd.h>
2*2d543d20SAndroid Build Coastguard Worker #include <fcntl.h>
3*2d543d20SAndroid Build Coastguard Worker #include <string.h>
4*2d543d20SAndroid Build Coastguard Worker #include <stdlib.h>
5*2d543d20SAndroid Build Coastguard Worker #include <errno.h>
6*2d543d20SAndroid Build Coastguard Worker #include <stdio.h>
7*2d543d20SAndroid Build Coastguard Worker #include <sys/xattr.h>
8*2d543d20SAndroid Build Coastguard Worker #include "selinux_internal.h"
9*2d543d20SAndroid Build Coastguard Worker #include "policy.h"
10*2d543d20SAndroid Build Coastguard Worker 
fsetxattr_wrapper(int fd,const char * name,const void * value,size_t size,int flags)11*2d543d20SAndroid Build Coastguard Worker static int fsetxattr_wrapper(int fd, const char* name, const void* value, size_t size, int flags) {
12*2d543d20SAndroid Build Coastguard Worker 	char buf[40];
13*2d543d20SAndroid Build Coastguard Worker 	int rc, fd_flag, saved_errno = errno;
14*2d543d20SAndroid Build Coastguard Worker 
15*2d543d20SAndroid Build Coastguard Worker 	rc = fsetxattr(fd, name, value, size, flags);
16*2d543d20SAndroid Build Coastguard Worker 	if (rc == 0 || errno != EBADF)
17*2d543d20SAndroid Build Coastguard Worker 		return rc;
18*2d543d20SAndroid Build Coastguard Worker 
19*2d543d20SAndroid Build Coastguard Worker 	/* Emulate O_PATH support */
20*2d543d20SAndroid Build Coastguard Worker 	fd_flag = fcntl(fd, F_GETFL);
21*2d543d20SAndroid Build Coastguard Worker 	if (fd_flag == -1 || (fd_flag & O_PATH) == 0) {
22*2d543d20SAndroid Build Coastguard Worker 		errno = EBADF;
23*2d543d20SAndroid Build Coastguard Worker 		return -1;
24*2d543d20SAndroid Build Coastguard Worker 	}
25*2d543d20SAndroid Build Coastguard Worker 
26*2d543d20SAndroid Build Coastguard Worker 	snprintf(buf, sizeof(buf), "/proc/self/fd/%d", fd);
27*2d543d20SAndroid Build Coastguard Worker 	errno = saved_errno;
28*2d543d20SAndroid Build Coastguard Worker 	rc = setxattr(buf, name, value, size, flags);
29*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0 && errno == ENOENT)
30*2d543d20SAndroid Build Coastguard Worker 		errno = EBADF;
31*2d543d20SAndroid Build Coastguard Worker 	return rc;
32*2d543d20SAndroid Build Coastguard Worker }
33*2d543d20SAndroid Build Coastguard Worker 
fsetfilecon_raw(int fd,const char * context)34*2d543d20SAndroid Build Coastguard Worker int fsetfilecon_raw(int fd, const char * context)
35*2d543d20SAndroid Build Coastguard Worker {
36*2d543d20SAndroid Build Coastguard Worker 	int rc = fsetxattr_wrapper(fd, XATTR_NAME_SELINUX, context, strlen(context) + 1,
37*2d543d20SAndroid Build Coastguard Worker 			 0);
38*2d543d20SAndroid Build Coastguard Worker 	if (rc < 0 && errno == ENOTSUP) {
39*2d543d20SAndroid Build Coastguard Worker 		char * ccontext = NULL;
40*2d543d20SAndroid Build Coastguard Worker 		int err = errno;
41*2d543d20SAndroid Build Coastguard Worker 		if ((fgetfilecon_raw(fd, &ccontext) >= 0) &&
42*2d543d20SAndroid Build Coastguard Worker 		    (strcmp(context,ccontext) == 0)) {
43*2d543d20SAndroid Build Coastguard Worker 			rc = 0;
44*2d543d20SAndroid Build Coastguard Worker 		} else {
45*2d543d20SAndroid Build Coastguard Worker 			errno = err;
46*2d543d20SAndroid Build Coastguard Worker 		}
47*2d543d20SAndroid Build Coastguard Worker 		freecon(ccontext);
48*2d543d20SAndroid Build Coastguard Worker 	}
49*2d543d20SAndroid Build Coastguard Worker 	return rc;
50*2d543d20SAndroid Build Coastguard Worker }
51*2d543d20SAndroid Build Coastguard Worker 
52*2d543d20SAndroid Build Coastguard Worker 
fsetfilecon(int fd,const char * context)53*2d543d20SAndroid Build Coastguard Worker int fsetfilecon(int fd, const char *context)
54*2d543d20SAndroid Build Coastguard Worker {
55*2d543d20SAndroid Build Coastguard Worker 	int ret;
56*2d543d20SAndroid Build Coastguard Worker 	char * rcontext;
57*2d543d20SAndroid Build Coastguard Worker 
58*2d543d20SAndroid Build Coastguard Worker 	if (selinux_trans_to_raw_context(context, &rcontext))
59*2d543d20SAndroid Build Coastguard Worker 		return -1;
60*2d543d20SAndroid Build Coastguard Worker 
61*2d543d20SAndroid Build Coastguard Worker 	ret = fsetfilecon_raw(fd, rcontext);
62*2d543d20SAndroid Build Coastguard Worker 
63*2d543d20SAndroid Build Coastguard Worker 	freecon(rcontext);
64*2d543d20SAndroid Build Coastguard Worker 
65*2d543d20SAndroid Build Coastguard Worker 	return ret;
66*2d543d20SAndroid Build Coastguard Worker }
67