From 49363b32fe3025161f9c137b897a243c71142456 Mon Sep 17 00:00:00 2001 From: Rafal Krypa Date: Thu, 2 Jan 2014 13:52:17 +0100 Subject: [PATCH] libsmack: use common code for smack_accesses_apply() and smack_accesses_save(). Centralizing code that changes internal smack_accesses representation to text. Internal function accesses_print() now generates output for applying the rules to kernel and saving them to a file. This allows easier changes to data structures used by libmskack and makes the code shorter. Signed-off-by: Rafal Krypa --- libsmack/libsmack.c | 124 ++++++++++++++++++++-------------------------------- 1 file changed, 47 insertions(+), 77 deletions(-) diff --git a/libsmack/libsmack.c b/libsmack/libsmack.c index a03f6eb..2e23b79 100644 --- a/libsmack/libsmack.c +++ b/libsmack/libsmack.c @@ -107,6 +107,8 @@ static int dict_create(struct label_dict **dict); static int dict_free(struct label_dict *dict); static const char *dict_get_label(const struct label_dict *dict, int id); static ssize_t dict_add_label(struct label_dict *dict, int *id, const char *src); +static int accesses_print(struct smack_accesses *handle, int clear, + int load_fd, int change_fd, int use_long, int add_lf); int smack_accesses_new(struct smack_accesses **accesses) { @@ -142,50 +144,7 @@ void smack_accesses_free(struct smack_accesses *handle) int smack_accesses_save(struct smack_accesses *handle, int fd) { - struct smack_rule *rule = handle->first; - char allow_str[ACC_LEN + 1]; - char deny_str[ACC_LEN + 1]; - FILE *file; - int ret; - int newfd; - - newfd = dup(fd); - if (newfd == -1) - return -1; - - file = fdopen(newfd, "w"); - if (file == NULL) { - close(newfd); - return -1; - } - - while (rule) { - access_code_to_str(rule->allow_code, allow_str); - - if (rule->deny_code != -1) /* modify? */ { - access_code_to_str(rule->deny_code, deny_str); - - ret = fprintf(file, "%s %s %s %s\n", - dict_get_label(handle->dict, rule->subject_id), - dict_get_label(handle->dict, rule->object_id), - allow_str, deny_str); - } else { - ret = fprintf(file, "%s %s %s\n", - dict_get_label(handle->dict, rule->subject_id), - dict_get_label(handle->dict, rule->object_id), - allow_str); - } - - if (ret < 0) { - fclose(file); - return -1; - } - - rule = rule->next; - } - - fclose(file); - return 0; + return accesses_print(handle, 0, fd, fd, 1, 1); } int smack_accesses_apply(struct smack_accesses *handle) @@ -639,12 +598,7 @@ int smack_revoke_subject(const char *subject) static int accesses_apply(struct smack_accesses *handle, int clear) { - char buf[LOAD_LEN + 1]; - char allow_str[ACC_LEN + 1]; - char deny_str[ACC_LEN + 1]; - struct smack_rule *rule; int ret; - int fd; int load_fd; int change_fd; int load2 = 1; @@ -671,13 +625,33 @@ static int accesses_apply(struct smack_accesses *handle, int clear) goto err_out; } + ret = accesses_print(handle, clear, load_fd, change_fd, load2, 0); + +err_out: + if (load_fd >= 0) + close(load_fd); + if (change_fd >= 0) + close(change_fd); + return ret; +} + +static int accesses_print(struct smack_accesses *handle, int clear, + int load_fd, int change_fd, int use_long, int add_lf) +{ + char buf[LOAD_LEN + 1]; + char allow_str[ACC_LEN + 1]; + char deny_str[ACC_LEN + 1]; + struct smack_rule *rule; + int ret; + int fd; + int i; + int cnt; + for (rule = handle->first; rule != NULL; rule = rule->next) { /* Fail immediately without doing any further processing if modify rules are not supported. */ - if (rule->deny_code >= 0 && change_fd < 0) { - ret = -1; - goto err_out; - } + if (rule->deny_code >= 0 && change_fd < 0) + return -1; access_code_to_str(clear ? 0 : rule->allow_code, allow_str); @@ -685,51 +659,47 @@ static int accesses_apply(struct smack_accesses *handle, int clear) access_code_to_str(rule->deny_code, deny_str); fd = change_fd; - ret = snprintf(buf, LOAD_LEN + 1, KERNEL_MODIFY_FORMAT, + cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_MODIFY_FORMAT, dict_get_label(handle->dict, rule->subject_id), dict_get_label(handle->dict, rule->object_id), allow_str, deny_str); } else { fd = load_fd; - if (load2) - ret = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT, + if (use_long) + cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_LONG_FORMAT, dict_get_label(handle->dict, rule->subject_id), dict_get_label(handle->dict, rule->object_id), allow_str); else { if (rule->subject_len > SHORT_LABEL_LEN || - rule->object_len > SHORT_LABEL_LEN) { - ret = -1; - goto err_out; - } + rule->object_len > SHORT_LABEL_LEN) + return -1; - ret = snprintf(buf, LOAD_LEN + 1, KERNEL_SHORT_FORMAT, + cnt = snprintf(buf, LOAD_LEN + 1, KERNEL_SHORT_FORMAT, dict_get_label(handle->dict, rule->subject_id), dict_get_label(handle->dict, rule->object_id), allow_str); } } - if (ret < 0) { - ret = -1; - goto err_out; - } - - ret = write(fd, buf, ret); - if (ret < 0) { - ret = -1; - goto err_out; + if (cnt < 0) + return -1; + if (add_lf) + buf[cnt++] = '\n'; + + for (i = 0; i < cnt; ) { + ret = write(fd, buf + i, cnt - i); + if (ret == -1) { + if (errno == EINTR) + continue; + return -1; + } + i += ret; } } - ret = 0; -err_out: - if (load_fd >= 0) - close(load_fd); - if (change_fd >= 0) - close(change_fd); - return ret; + return 0; } static inline ssize_t get_label(char *dest, const char *src) -- 2.7.4