diff options
author | Janusz Kozerski <j.kozerski@samsung.com> | 2014-05-20 17:28:26 +0200 |
---|---|---|
committer | Janusz Kozerski <j.kozerski@samsung.com> | 2014-10-09 16:30:06 +0200 |
commit | c65ec844a0a87db716bc07689122706e45b4d088 (patch) | |
tree | ef11c5c44888286aabcc6c9fa81027c68d0a293c | |
parent | 0a7a657aa83eb21b7bd0b6b96643752a7dfe9ed7 (diff) | |
download | ima-evm-utils-c65ec844a0a87db716bc07689122706e45b4d088.tar.gz ima-evm-utils-c65ec844a0a87db716bc07689122706e45b4d088.tar.bz2 ima-evm-utils-c65ec844a0a87db716bc07689122706e45b4d088.zip |
Add ima_set_policy function.
Function takes two parameters:
char **policy - which is NULL terminated list of strings.
char *signature - signature of the policy.
Change-Id: I8ecdf91ce4e8d122c69d2f86b18fc7202da5a053
Signed-off-by: Janusz Kozerski <j.kozerski@samsung.com>
-rw-r--r-- | src/imaevm.h | 1 | ||||
-rw-r--r-- | src/libimaevm.c | 161 |
2 files changed, 161 insertions, 1 deletions
diff --git a/src/imaevm.h b/src/imaevm.h index b6e380e..3e60d76 100644 --- a/src/imaevm.h +++ b/src/imaevm.h @@ -233,5 +233,6 @@ int evm_get_xattr(const char *path, char **hash); int ima_get_policy(char*** policy); int ima_free_policy(char **policy); +int ima_set_policy(const char **policy, const char *policy_sig); #endif diff --git a/src/libimaevm.c b/src/libimaevm.c index 5c0d69f..8ada490 100644 --- a/src/libimaevm.c +++ b/src/libimaevm.c @@ -802,7 +802,10 @@ 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" +#define IMA_POLICY_INTERFACE "/sys/kernel/security/ima/policy" +#define IMA_POLICY_TMP_DIR "/tmp/" +#define IMA_POLICY_TMP_FILE_PREFIX "ima_" +#define IMA_POLICY_SIGNATRURE_EXTENSION ".sig" int ima_get_state(int *state) { @@ -1192,3 +1195,159 @@ int ima_free_policy(char **policy) return LIB_SUCCESS; } + +static int _ima_write_rule(int fd, const char *rule) +{ + int counter = 0; + int ret; + + if (fd < 0) + return LIB_ERROR_SYSCALL; + if (!rule) + return LIB_SUCCESS; + + int len = strlen(rule); + + /* writing rule */ + while (counter < len) { + ret = write(fd, &(rule[counter]), len-counter); + if (ret < 0) { /* Write error. Return with error code */ + return LIB_ERROR_SYSCALL; + } + counter += ret; + } + + /* writing new line sign */ + do { + ret = write(fd, "\n", sizeof("\n")); + if (ret < 0) + return LIB_ERROR_SYSCALL; + } while (!ret); + if (ret != sizeof("\n")) + return LIB_ERROR_SYSCALL; + + return LIB_SUCCESS; +} + + +int ima_set_policy(const char **policy, const char *policy_sig) +{ + int ret_code = LIB_SUCCESS; + char *policy_file_name = NULL; + char *sig_file_name = NULL; + int fd_policy = -1; + int fd_sig = -1; + int fd = -1; + int i, counter, len; + int ret; + + if (!policy || !policy_sig) { + log_err("Error input param\n"); + return LIB_ERROR_INPUT_PARAM; + } + + /* Generate random filename */ + policy_file_name = tempnam(IMA_POLICY_TMP_DIR, IMA_POLICY_TMP_FILE_PREFIX); + if (!policy_file_name) { + log_err("Cannot generate unique file name\n"); + return LIB_ERROR_SYSCALL; + } + + /* write policy to temporary file */ + /* We need to be sure that we create a new file. */ + /* No one should have any right to this file - except write for us */ + fd_policy = open(policy_file_name, O_WRONLY | O_CREAT | O_EXCL, S_IWUSR); + if (fd_policy < 0) { + log_err("Cannot open policy temporary file\n"); + ret_code = LIB_ERROR_SYSCALL; + goto out; + } + + i = 0; + while (policy[i]) { + ret = _ima_write_rule(fd_policy, policy[i]); + if (ret != LIB_SUCCESS) { + log_err("Error while writing policy rule to temporary file\n"); + ret_code = ret; + goto out; + } + ++i; + } + /* We keep this file locked */ + + /* generate signature file name */ + sig_file_name = malloc(sizeof(char) * (strlen(policy_file_name) + sizeof(IMA_POLICY_SIGNATRURE_EXTENSION) + 1)); + if (!sig_file_name) { + ret_code = LIB_ERROR_MEMORY; + goto out; + } + len = strlen(policy_file_name); + memcpy(sig_file_name, policy_file_name, len); + memcpy(&(sig_file_name[len]), + IMA_POLICY_SIGNATRURE_EXTENSION, + sizeof(IMA_POLICY_SIGNATRURE_EXTENSION)); + sig_file_name[len + sizeof(IMA_POLICY_SIGNATRURE_EXTENSION)] = '\0'; + + /* write signature to temporary file - the same conditions as for the policy file */ + fd_sig = open(sig_file_name, O_WRONLY | O_CREAT | O_EXCL, S_IWUSR); + if (fd_sig < 0) { + log_err("Cannot open signature temporary file\n"); + ret_code = LIB_ERROR_SYSCALL; + goto out; + } + + counter = 0; + len = strlen(policy_sig); + while (counter < len) { + ret = write(fd_sig, &(policy_sig[counter]), len-counter); + if (ret < 0) { + log_err("Error while writing signature to temporary file\n"); + ret_code = LIB_ERROR_SYSCALL; + goto out; + } + counter += ret; + } + + /* unlocked policy and signature file */ + if (fd_policy > -1) + close(fd_policy); + if (fd_sig > -1) + close(fd_sig); + + /* open and write to kernel interface */ + fd = open(IMA_POLICY_INTERFACE, O_WRONLY); + if (fd < 0) { + log_err("Cannot open kernel interface\n"); + ret_code = LIB_ERROR_SYSCALL; + goto out; + } + + counter = 0; + len = strlen(policy_file_name); + while (counter < len) { + ret = write(fd, &(policy_file_name[counter]), len-counter); + if (ret < 0) { + log_err("Error while writing to the kernel interface\n"); + ret_code = LIB_ERROR_SYSCALL; + goto out; + } + counter += ret; + } + +out: + if (fd_policy > -1) + close(fd_policy); + if (fd_sig > -1) + close(fd_sig); + if (fd > -1) + close(fd); + if (policy_file_name) { + unlink(policy_file_name); + free(policy_file_name); + } + if (sig_file_name) { + unlink(sig_file_name); + free(sig_file_name); + } + return ret_code; +} |