16cd6a6acSopenharmony_ci#include <unistd.h>
26cd6a6acSopenharmony_ci#include <fcntl.h>
36cd6a6acSopenharmony_ci#include <string.h>
46cd6a6acSopenharmony_ci#include "selinux_internal.h"
56cd6a6acSopenharmony_ci#include <stdlib.h>
66cd6a6acSopenharmony_ci#include <errno.h>
76cd6a6acSopenharmony_ci#include <sys/xattr.h>
86cd6a6acSopenharmony_ci#include "policy.h"
96cd6a6acSopenharmony_ci
106cd6a6acSopenharmony_ciint getfilecon_raw(const char *path, char ** context)
116cd6a6acSopenharmony_ci{
126cd6a6acSopenharmony_ci	char *buf;
136cd6a6acSopenharmony_ci	ssize_t size;
146cd6a6acSopenharmony_ci	ssize_t ret;
156cd6a6acSopenharmony_ci
166cd6a6acSopenharmony_ci	size = INITCONTEXTLEN + 1;
176cd6a6acSopenharmony_ci	buf = malloc(size);
186cd6a6acSopenharmony_ci	if (!buf)
196cd6a6acSopenharmony_ci		return -1;
206cd6a6acSopenharmony_ci	memset(buf, 0, size);
216cd6a6acSopenharmony_ci
226cd6a6acSopenharmony_ci	ret = getxattr(path, XATTR_NAME_SELINUX, buf, size - 1);
236cd6a6acSopenharmony_ci	if (ret < 0 && errno == ERANGE) {
246cd6a6acSopenharmony_ci		char *newbuf;
256cd6a6acSopenharmony_ci
266cd6a6acSopenharmony_ci		size = getxattr(path, XATTR_NAME_SELINUX, NULL, 0);
276cd6a6acSopenharmony_ci		if (size < 0)
286cd6a6acSopenharmony_ci			goto out;
296cd6a6acSopenharmony_ci
306cd6a6acSopenharmony_ci		size++;
316cd6a6acSopenharmony_ci		newbuf = realloc(buf, size);
326cd6a6acSopenharmony_ci		if (!newbuf)
336cd6a6acSopenharmony_ci			goto out;
346cd6a6acSopenharmony_ci
356cd6a6acSopenharmony_ci		buf = newbuf;
366cd6a6acSopenharmony_ci		memset(buf, 0, size);
376cd6a6acSopenharmony_ci		ret = getxattr(path, XATTR_NAME_SELINUX, buf, size - 1);
386cd6a6acSopenharmony_ci	}
396cd6a6acSopenharmony_ci      out:
406cd6a6acSopenharmony_ci	if (ret == 0) {
416cd6a6acSopenharmony_ci		/* Re-map empty attribute values to errors. */
426cd6a6acSopenharmony_ci		errno = ENOTSUP;
436cd6a6acSopenharmony_ci		ret = -1;
446cd6a6acSopenharmony_ci	}
456cd6a6acSopenharmony_ci	if (ret < 0)
466cd6a6acSopenharmony_ci		free(buf);
476cd6a6acSopenharmony_ci	else
486cd6a6acSopenharmony_ci		*context = buf;
496cd6a6acSopenharmony_ci	return ret;
506cd6a6acSopenharmony_ci}
516cd6a6acSopenharmony_ci
526cd6a6acSopenharmony_ci
536cd6a6acSopenharmony_ciint getfilecon(const char *path, char ** context)
546cd6a6acSopenharmony_ci{
556cd6a6acSopenharmony_ci	int ret;
566cd6a6acSopenharmony_ci	char * rcontext = NULL;
576cd6a6acSopenharmony_ci
586cd6a6acSopenharmony_ci	*context = NULL;
596cd6a6acSopenharmony_ci
606cd6a6acSopenharmony_ci	ret = getfilecon_raw(path, &rcontext);
616cd6a6acSopenharmony_ci
626cd6a6acSopenharmony_ci	if (ret > 0) {
636cd6a6acSopenharmony_ci		ret = selinux_raw_to_trans_context(rcontext, context);
646cd6a6acSopenharmony_ci		freecon(rcontext);
656cd6a6acSopenharmony_ci	}
666cd6a6acSopenharmony_ci	if (ret >= 0 && *context)
676cd6a6acSopenharmony_ci		return strlen(*context) + 1;
686cd6a6acSopenharmony_ci
696cd6a6acSopenharmony_ci	return ret;
706cd6a6acSopenharmony_ci}
716cd6a6acSopenharmony_ci
72