Commit 57bb8e37 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'apparmor-pr-2018-08-23' of...

Merge tag 'apparmor-pr-2018-08-23' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor

Pull apparmor updates from John Johansen:
 "There is nothing major this time just four bug fixes and a patch to
  remove some dead code:

  Cleanups:
   - remove no-op permission check in policy_unpack

  Bug fixes:
   - fix an error code in __aa_create_ns()
   - fix failure to audit context info in build_change_hat
   - check buffer bounds when mapping permissions mask
   - fully initialize aa_perms struct when answering userspace query"

* tag 'apparmor-pr-2018-08-23' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor:
  apparmor: remove no-op permission check in policy_unpack
  apparmor: fix an error code in __aa_create_ns()
  apparmor: Fix failure to audit context info in build_change_hat
  apparmor: Fully initialize aa_perms struct when answering userspace query
  apparmor: Check buffer bounds when mapping permissions mask
parents aa5b1054 c037bd61
...@@ -603,7 +603,7 @@ static const struct file_operations aa_fs_ns_revision_fops = { ...@@ -603,7 +603,7 @@ static const struct file_operations aa_fs_ns_revision_fops = {
static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms, static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
const char *match_str, size_t match_len) const char *match_str, size_t match_len)
{ {
struct aa_perms tmp; struct aa_perms tmp = { };
struct aa_dfa *dfa; struct aa_dfa *dfa;
unsigned int state = 0; unsigned int state = 0;
...@@ -613,7 +613,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms, ...@@ -613,7 +613,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
dfa = profile->file.dfa; dfa = profile->file.dfa;
state = aa_dfa_match_len(dfa, profile->file.start, state = aa_dfa_match_len(dfa, profile->file.start,
match_str + 1, match_len - 1); match_str + 1, match_len - 1);
tmp = nullperms;
if (state) { if (state) {
struct path_cond cond = { }; struct path_cond cond = { };
...@@ -627,8 +626,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms, ...@@ -627,8 +626,6 @@ static void profile_query_cb(struct aa_profile *profile, struct aa_perms *perms,
match_str, match_len); match_str, match_len);
if (state) if (state)
aa_compute_perms(dfa, state, &tmp); aa_compute_perms(dfa, state, &tmp);
else
tmp = nullperms;
} }
aa_apply_modes_to_perms(profile, &tmp); aa_apply_modes_to_perms(profile, &tmp);
aa_perms_accum_raw(perms, &tmp); aa_perms_accum_raw(perms, &tmp);
......
...@@ -1036,7 +1036,7 @@ static struct aa_label *build_change_hat(struct aa_profile *profile, ...@@ -1036,7 +1036,7 @@ static struct aa_label *build_change_hat(struct aa_profile *profile,
audit: audit:
aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT, aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT,
name, hat ? hat->base.hname : NULL, name, hat ? hat->base.hname : NULL,
hat ? &hat->label : NULL, GLOBAL_ROOT_UID, NULL, hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info,
error); error);
if (!hat || (error && error != -ENOENT)) if (!hat || (error && error != -ENOENT))
return ERR_PTR(error); return ERR_PTR(error);
......
...@@ -47,7 +47,8 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask) ...@@ -47,7 +47,8 @@ static void audit_file_mask(struct audit_buffer *ab, u32 mask)
{ {
char str[10]; char str[10];
aa_perm_mask_to_str(str, aa_file_perm_chrs, map_mask_to_chr_mask(mask)); aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
map_mask_to_chr_mask(mask));
audit_log_string(ab, str); audit_log_string(ab, str);
} }
......
...@@ -137,7 +137,8 @@ extern struct aa_perms allperms; ...@@ -137,7 +137,8 @@ extern struct aa_perms allperms;
xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2))) xcheck(fn_for_each((L1), (P), (FN1)), fn_for_each((L2), (P), (FN2)))
void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask); void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs,
u32 mask);
void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names, void aa_audit_perm_names(struct audit_buffer *ab, const char * const *names,
u32 mask); u32 mask);
void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
......
...@@ -198,15 +198,24 @@ const char *aa_file_perm_names[] = { ...@@ -198,15 +198,24 @@ const char *aa_file_perm_names[] = {
/** /**
* aa_perm_mask_to_str - convert a perm mask to its short string * aa_perm_mask_to_str - convert a perm mask to its short string
* @str: character buffer to store string in (at least 10 characters) * @str: character buffer to store string in (at least 10 characters)
* @str_size: size of the @str buffer
* @chrs: NUL-terminated character buffer of permission characters
* @mask: permission mask to convert * @mask: permission mask to convert
*/ */
void aa_perm_mask_to_str(char *str, const char *chrs, u32 mask) void aa_perm_mask_to_str(char *str, size_t str_size, const char *chrs, u32 mask)
{ {
unsigned int i, perm = 1; unsigned int i, perm = 1;
size_t num_chrs = strlen(chrs);
for (i = 0; i < num_chrs; perm <<= 1, i++) {
if (mask & perm) {
/* Ensure that one byte is left for NUL-termination */
if (WARN_ON_ONCE(str_size <= 1))
break;
for (i = 0; i < 32; perm <<= 1, i++) {
if (mask & perm)
*str++ = chrs[i]; *str++ = chrs[i];
str_size--;
}
} }
*str = '\0'; *str = '\0';
} }
...@@ -236,7 +245,7 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, ...@@ -236,7 +245,7 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs,
audit_log_format(ab, "\""); audit_log_format(ab, "\"");
if ((mask & chrsmask) && chrs) { if ((mask & chrsmask) && chrs) {
aa_perm_mask_to_str(str, chrs, mask & chrsmask); aa_perm_mask_to_str(str, sizeof(str), chrs, mask & chrsmask);
mask &= ~chrsmask; mask &= ~chrsmask;
audit_log_format(ab, "%s", str); audit_log_format(ab, "%s", str);
if (mask & namesmask) if (mask & namesmask)
......
...@@ -255,7 +255,7 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name, ...@@ -255,7 +255,7 @@ static struct aa_ns *__aa_create_ns(struct aa_ns *parent, const char *name,
ns = alloc_ns(parent->base.hname, name); ns = alloc_ns(parent->base.hname, name);
if (!ns) if (!ns)
return NULL; return ERR_PTR(-ENOMEM);
ns->level = parent->level + 1; ns->level = parent->level + 1;
mutex_lock_nested(&ns->lock, ns->level); mutex_lock_nested(&ns->lock, ns->level);
error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir); error = __aafs_ns_mkdir(ns, ns_subns_dir(parent), name, dir);
......
...@@ -389,32 +389,6 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name) ...@@ -389,32 +389,6 @@ static int unpack_strdup(struct aa_ext *e, char **string, const char *name)
return res; return res;
} }
#define DFA_VALID_PERM_MASK 0xffffffff
#define DFA_VALID_PERM2_MASK 0xffffffff
/**
* verify_accept - verify the accept tables of a dfa
* @dfa: dfa to verify accept tables of (NOT NULL)
* @flags: flags governing dfa
*
* Returns: 1 if valid accept tables else 0 if error
*/
static bool verify_accept(struct aa_dfa *dfa, int flags)
{
int i;
/* verify accept permissions */
for (i = 0; i < dfa->tables[YYTD_ID_ACCEPT]->td_lolen; i++) {
int mode = ACCEPT_TABLE(dfa)[i];
if (mode & ~DFA_VALID_PERM_MASK)
return 0;
if (ACCEPT_TABLE2(dfa)[i] & ~DFA_VALID_PERM2_MASK)
return 0;
}
return 1;
}
/** /**
* unpack_dfa - unpack a file rule dfa * unpack_dfa - unpack a file rule dfa
...@@ -445,15 +419,9 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e) ...@@ -445,15 +419,9 @@ static struct aa_dfa *unpack_dfa(struct aa_ext *e)
if (IS_ERR(dfa)) if (IS_ERR(dfa))
return dfa; return dfa;
if (!verify_accept(dfa, flags))
goto fail;
} }
return dfa; return dfa;
fail:
aa_put_dfa(dfa);
return ERR_PTR(-EPROTO);
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment