1f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <unistd.h> 2f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <sys/types.h> 3f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <fcntl.h> 4f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdlib.h> 5f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <stdio.h> 6f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <errno.h> 7f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <string.h> 8f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include <limits.h> 9f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "selinux_internal.h" 10f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "policy.h" 11f074036424618c130dacb3464465a8b40bffef5Stephen Smalley#include "mapping.h" 12f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 13ab40ea9bfd71b50138f1482c4764a65ac17d8cafStephen Smalleyint security_compute_av(const char * scon, 14ab40ea9bfd71b50138f1482c4764a65ac17d8cafStephen Smalley const char * tcon, 15f074036424618c130dacb3464465a8b40bffef5Stephen Smalley security_class_t tclass, 16f074036424618c130dacb3464465a8b40bffef5Stephen Smalley access_vector_t requested, 17f074036424618c130dacb3464465a8b40bffef5Stephen Smalley struct av_decision *avd) 18f074036424618c130dacb3464465a8b40bffef5Stephen Smalley{ 19f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char path[PATH_MAX]; 20f074036424618c130dacb3464465a8b40bffef5Stephen Smalley char *buf; 21f074036424618c130dacb3464465a8b40bffef5Stephen Smalley size_t len; 22f074036424618c130dacb3464465a8b40bffef5Stephen Smalley int fd, ret; 23f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 24f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (!selinux_mnt) { 25f074036424618c130dacb3464465a8b40bffef5Stephen Smalley errno = ENOENT; 26f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return -1; 27f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 28f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 29f074036424618c130dacb3464465a8b40bffef5Stephen Smalley snprintf(path, sizeof path, "%s/access", selinux_mnt); 30f074036424618c130dacb3464465a8b40bffef5Stephen Smalley fd = open(path, O_RDWR); 31f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (fd < 0) 32f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return -1; 33f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 34f074036424618c130dacb3464465a8b40bffef5Stephen Smalley len = selinux_page_size; 35f074036424618c130dacb3464465a8b40bffef5Stephen Smalley buf = malloc(len); 36f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (!buf) { 37f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = -1; 38f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto out; 39f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } 40f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 41f074036424618c130dacb3464465a8b40bffef5Stephen Smalley snprintf(buf, len, "%s %s %hu %x", scon, tcon, 42f074036424618c130dacb3464465a8b40bffef5Stephen Smalley unmap_class(tclass), unmap_perm(tclass, requested)); 43f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 44f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = write(fd, buf, strlen(buf)); 45f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (ret < 0) 46f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto out2; 47f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 48f074036424618c130dacb3464465a8b40bffef5Stephen Smalley memset(buf, 0, len); 49f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = read(fd, buf, len - 1); 50f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (ret < 0) 51f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto out2; 52f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 53f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = sscanf(buf, "%x %x %x %x %u %x", 54f074036424618c130dacb3464465a8b40bffef5Stephen Smalley &avd->allowed, &avd->decided, 55f074036424618c130dacb3464465a8b40bffef5Stephen Smalley &avd->auditallow, &avd->auditdeny, 56f074036424618c130dacb3464465a8b40bffef5Stephen Smalley &avd->seqno, &avd->flags); 57f074036424618c130dacb3464465a8b40bffef5Stephen Smalley if (ret < 5) { 58f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = -1; 59f074036424618c130dacb3464465a8b40bffef5Stephen Smalley goto out2; 60f074036424618c130dacb3464465a8b40bffef5Stephen Smalley } else if (ret < 6) 61f074036424618c130dacb3464465a8b40bffef5Stephen Smalley avd->flags = 0; 62f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 63f074036424618c130dacb3464465a8b40bffef5Stephen Smalley map_decision(tclass, avd); 64f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 65f074036424618c130dacb3464465a8b40bffef5Stephen Smalley ret = 0; 66f074036424618c130dacb3464465a8b40bffef5Stephen Smalley out2: 67f074036424618c130dacb3464465a8b40bffef5Stephen Smalley free(buf); 68f074036424618c130dacb3464465a8b40bffef5Stephen Smalley out: 69f074036424618c130dacb3464465a8b40bffef5Stephen Smalley close(fd); 70f074036424618c130dacb3464465a8b40bffef5Stephen Smalley return ret; 71f074036424618c130dacb3464465a8b40bffef5Stephen Smalley} 72f074036424618c130dacb3464465a8b40bffef5Stephen Smalley 73