if (aad(sa)->peer) {
audit_log_format(ab, " target=");
aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
- FLAG_VIEW_SUBNS, GFP_ATOMIC);
+ FLAG_VIEW_SUBNS, GFP_KERNEL);
} else if (aad(sa)->fs.target) {
audit_log_format(ab, " target=");
audit_log_untrustedstring(ab, aad(sa)->fs.target);
flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR :
0);
- get_buffers(buffer);
+ buffer = aa_get_buffer(false);
+ if (!buffer)
+ return -ENOMEM;
error = fn_for_each_confined(label, profile,
profile_path_perm(op, profile, path, buffer, request,
cond, flags, &perms));
- put_buffers(buffer);
+ aa_put_buffer(buffer);
return error;
}
int error;
/* buffer freed below, lname is pointer in buffer */
- get_buffers(buffer, buffer2);
+ buffer = aa_get_buffer(false);
+ buffer2 = aa_get_buffer(false);
+ error = -ENOMEM;
+ if (!buffer || !buffer2)
+ goto out;
+
error = fn_for_each_confined(label, profile,
profile_path_link(profile, &link, buffer, &target,
buffer2, &cond));
- put_buffers(buffer, buffer2);
-
+out:
+ aa_put_buffer(buffer);
+ aa_put_buffer(buffer2);
return error;
}
static int __file_path_perm(const char *op, struct aa_label *label,
struct aa_label *flabel, struct file *file,
- u32 request, u32 denied)
+ u32 request, u32 denied, bool in_atomic)
{
struct aa_profile *profile;
struct aa_perms perms = {};
return 0;
flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
- get_buffers(buffer);
+ buffer = aa_get_buffer(in_atomic);
+ if (!buffer)
+ return -ENOMEM;
/* check every profile in task label not in current cache */
error = fn_for_each_not_in_set(flabel, label, profile,
if (!error)
update_file_ctx(file_ctx(file), label, request);
- put_buffers(buffer);
+ aa_put_buffer(buffer);
return error;
}
* @label: label being enforced (NOT NULL)
* @file: file to revalidate access permissions on (NOT NULL)
* @request: requested permissions
+ * @in_atomic: whether allocations need to be done in atomic context
*
* Returns: %0 if access allowed else error
*/
int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
- u32 request)
+ u32 request, bool in_atomic)
{
struct aa_file_ctx *fctx;
struct aa_label *flabel;
fctx = file_ctx(file);
rcu_read_lock();
- flabel = rcu_dereference(fctx->label);
+ flabel = aa_get_newest_label(rcu_dereference(fctx->label));
+ rcu_read_unlock();
AA_BUG(!flabel);
/* revalidate access, if task is unconfined, or the cached cred
if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry))
error = __file_path_perm(op, label, flabel, file, request,
- denied);
+ denied, in_atomic);
else if (S_ISSOCK(file_inode(file)->i_mode))
error = __file_sock_perm(op, label, flabel, file, request,
denied);
done:
- rcu_read_unlock();
-
+ aa_put_label(flabel);
return error;
}
struct tty_file_private, list);
file = file_priv->file;
- if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE))
+ if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE,
+ IN_ATOMIC))
drop_tty = 1;
}
spin_unlock(&tty->files_lock);
{
struct aa_label *label = (struct aa_label *)p;
- if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file)))
+ if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file),
+ IN_ATOMIC))
return fd + 1;
return 0;
}