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