diff options
Diffstat (limited to 'libselinux/src/compute_create.c')
-rw-r--r-- | libselinux/src/compute_create.c | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/libselinux/src/compute_create.c b/libselinux/src/compute_create.c new file mode 100644 index 00000000..1c56f0fb --- /dev/null +++ b/libselinux/src/compute_create.c @@ -0,0 +1,94 @@ +#include <unistd.h> +#include <sys/types.h> +#include <fcntl.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <limits.h> +#include "selinux_internal.h" +#include "policy.h" +#include "mapping.h" + +int security_compute_create_raw(security_context_t scon, + security_context_t tcon, + security_class_t tclass, + security_context_t * newcon) +{ + char path[PATH_MAX]; + char *buf; + size_t size; + int fd, ret; + + if (!selinux_mnt) { + errno = ENOENT; + return -1; + } + + snprintf(path, sizeof path, "%s/create", selinux_mnt); + fd = open(path, O_RDWR); + if (fd < 0) + return -1; + + size = selinux_page_size; + buf = malloc(size); + if (!buf) { + ret = -1; + goto out; + } + snprintf(buf, size, "%s %s %hu", scon, tcon, unmap_class(tclass)); + + ret = write(fd, buf, strlen(buf)); + if (ret < 0) + goto out2; + + memset(buf, 0, size); + ret = read(fd, buf, size - 1); + if (ret < 0) + goto out2; + + *newcon = strdup(buf); + if (!(*newcon)) { + ret = -1; + goto out2; + } + ret = 0; + out2: + free(buf); + out: + close(fd); + return ret; +} + +hidden_def(security_compute_create_raw) + +int security_compute_create(security_context_t scon, + security_context_t tcon, + security_class_t tclass, + security_context_t * newcon) +{ + int ret; + security_context_t rscon = scon; + security_context_t rtcon = tcon; + security_context_t rnewcon; + + if (selinux_trans_to_raw_context(scon, &rscon)) + return -1; + if (selinux_trans_to_raw_context(tcon, &rtcon)) { + freecon(rscon); + return -1; + } + + ret = security_compute_create_raw(rscon, rtcon, tclass, &rnewcon); + + freecon(rscon); + freecon(rtcon); + if (!ret) { + ret = selinux_raw_to_trans_context(rnewcon, newcon); + freecon(rnewcon); + } + + return ret; +} + +hidden_def(security_compute_create) |