Home | History | Annotate | Download | only in src
      1 #include <unistd.h>
      2 #include <fcntl.h>
      3 #include <string.h>
      4 #include <stdlib.h>
      5 #include <errno.h>
      6 #include <sys/xattr.h>
      7 #include "selinux_internal.h"
      8 #include "policy.h"
      9 
     10 int fgetfilecon_raw(int fd, char ** context)
     11 {
     12 	char *buf;
     13 	ssize_t size;
     14 	ssize_t ret;
     15 
     16 	size = INITCONTEXTLEN + 1;
     17 	buf = malloc(size);
     18 	if (!buf)
     19 		return -1;
     20 	memset(buf, 0, size);
     21 
     22 	ret = fgetxattr(fd, XATTR_NAME_SELINUX, buf, size - 1);
     23 	if (ret < 0 && errno == ERANGE) {
     24 		char *newbuf;
     25 
     26 		size = fgetxattr(fd, XATTR_NAME_SELINUX, NULL, 0);
     27 		if (size < 0)
     28 			goto out;
     29 
     30 		size++;
     31 		newbuf = realloc(buf, size);
     32 		if (!newbuf)
     33 			goto out;
     34 
     35 		buf = newbuf;
     36 		memset(buf, 0, size);
     37 		ret = fgetxattr(fd, XATTR_NAME_SELINUX, buf, size - 1);
     38 	}
     39       out:
     40 	if (ret == 0) {
     41 		/* Re-map empty attribute values to errors. */
     42 		errno = ENOTSUP;
     43 		ret = -1;
     44 	}
     45 	if (ret < 0)
     46 		free(buf);
     47 	else
     48 		*context = buf;
     49 	return ret;
     50 }
     51 
     52 hidden_def(fgetfilecon_raw)
     53 
     54 int fgetfilecon(int fd, char ** context)
     55 {
     56 	char * rcontext;
     57 	int ret;
     58 
     59 	*context = NULL;
     60 
     61 	ret = fgetfilecon_raw(fd, &rcontext);
     62 
     63 	if (ret > 0) {
     64 		ret = selinux_raw_to_trans_context(rcontext, context);
     65 		freecon(rcontext);
     66 	}
     67 
     68 	if (ret >= 0 && *context)
     69 		return strlen(*context) + 1;
     70 
     71 	return ret;
     72 }
     73