Add ima_get_policy() function 48/28548/1
authorJanusz Kozerski <j.kozerski@samsung.com>
Tue, 6 May 2014 13:17:38 +0000 (15:17 +0200)
committerJanusz Kozerski <j.kozerski@samsung.com>
Thu, 9 Oct 2014 14:29:51 +0000 (16:29 +0200)
Function return (via param) IMA policy from the kernel.
The policy is stored in NULL terminated list of char*.
The memory is mallocated by this function, and should be freed
by the caller.

Change-Id: I442ec1ed41d91306627781c076d3d4bcb04eb4cb
Signed-off-by: Janusz Kozerski <j.kozerski@samsung.com>
src/imaevm.h
src/libimaevm.c

index 9e7a931..101dd21 100644 (file)
@@ -230,5 +230,6 @@ int ima_set_xattr(const char *path);
 int ima_get_xattr(const char *path, char **hash);
 int evm_set_xattr(const char *path, const char *evm);
 int evm_get_xattr(const char *path, char **hash);
+int ima_get_policy(char*** policy);
 
 #endif
index 017d6a5..3a79a26 100644 (file)
@@ -802,6 +802,8 @@ int sign_hash(const char *hashalgo, const unsigned char *hash, int size, const c
 #define EVM_STATE_PATH  "/sys/kernel/security/evm/evm_state"
 #define EVM_XATTR   "security.evm"
 
+#define IMA_POLICY_INTERFACE  "/sys/kernel/security/ima/policy"
+
 int ima_get_state(int *state)
 {
        int fd;
@@ -1069,3 +1071,107 @@ int evm_get_xattr(const char *path, char **hash)
 
        return LIB_SUCCESS;
 }
+
+int ima_get_policy(char*** policy)
+{
+       char buff[100];
+       char *policy_tmp = NULL;
+       char *last;
+       char *last2;
+       int length = 0;
+       int rules_count;
+       int ret;
+       int ret_code = LIB_SUCCESS;
+       int i;
+
+       if (!policy)
+               return LIB_ERROR_INPUT_PARAM;
+
+       int fd = open(IMA_POLICY_INTERFACE, O_RDONLY);
+       if (fd < 0) {
+               log_err("Unable to open %s file\n", IMA_POLICY_INTERFACE);
+               return LIB_ERROR_SYSCALL;
+       }
+
+       // Read policy from fd to policy_tmp;
+       do {
+               ret = read(fd, &buff, sizeof(buff));
+               if (ret < 0) {
+                       log_err("Unable to read %s file\n", IMA_POLICY_INTERFACE);
+                       ret_code = LIB_ERROR_SYSCALL;
+                       goto out;
+               }
+               last = realloc(policy_tmp, length + ret + 1);
+               if (!last) { // realloc error
+                       ret_code = LIB_ERROR_MEMORY;
+                       goto out;
+               }
+               policy_tmp = last;
+               memcpy(&(policy_tmp[length]), buff, ret);
+               length += ret;
+       } while (ret == (int) sizeof(buff)); // If not whole buffer was filled then it means that the
+                                            // whole policy was read. Exit the while loop.
+       policy_tmp[length] = '\0';
+
+       if (length <= 1) { // Empty policy;
+               *policy = malloc(sizeof(char*));
+               if (!(*policy)) {
+                       ret_code = LIB_ERROR_MEMORY;
+                       goto out;
+               }
+               (*policy)[0] = NULL;
+               goto out;
+       }
+
+       // Counting rules
+       last = policy_tmp;
+       rules_count = 1; // Start counting from 1 because there can be one more rule then new line sign
+       while ((last = strchr(last, '\n'))) {
+               last += sizeof(char);
+               rules_count++;
+       }
+
+       *policy = malloc(sizeof(char*) * (rules_count + 1)); // +1 because this is null terminated list
+       if (!(*policy)) {
+               ret_code = LIB_ERROR_MEMORY;
+               goto out;
+       }
+       (*policy)[rules_count] = NULL;
+       last = policy_tmp;
+
+       // Re-write rules as a list of strings - every rule in different string.
+       for (i = 0; i < rules_count; ++i) {
+               last2 = strchr(last, '\n');
+               if (last2) {
+                       (*policy)[i] = malloc(sizeof(char*) * (last2 - last) + 1);
+                       if (!((*policy)[i])) {
+                               for (; i >= 0; --i)
+                                       free((*policy)[i]);
+                               free(*policy);
+                               *policy = NULL;
+                               ret_code = LIB_ERROR_MEMORY;
+                               goto out;
+                       }
+                       memcpy((*policy)[i], last, (last2 - last));
+                       (*policy)[i][last2 - last] = '\0';
+               } else { // This should be the last run of FOR loop
+                       (*policy)[i] = malloc(sizeof(char*) * strlen(last) + 1);
+                       if (!((*policy)[i])) {
+                               for (; i >= 0; --i)
+                                       free((*policy)[i]);
+                               free(*policy);
+                               *policy = NULL;
+                               ret_code = LIB_ERROR_MEMORY;
+                               goto out;
+                       }
+                       memcpy((*policy)[i], last, strlen(last));
+                       (*policy)[i][strlen(last)] = '\0';
+               }
+               last = last2 + sizeof(char);
+       }
+
+out:
+       close(fd);
+       free(policy_tmp);
+       return ret_code;
+}