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
10int 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
52hidden_def(fgetfilecon_raw)
53
54int 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