Update Linux to v5.10.109
Sourced from [1]
[1] https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.10.109.tar.xz
Change-Id: I19bca9fc6762d4e63bcf3e4cba88bbe560d9c76c
Signed-off-by: Olivier Deprez <olivier.deprez@arm.com>
diff --git a/security/apparmor/file.c b/security/apparmor/file.c
index 4c1b05e..92acf9a 100644
--- a/security/apparmor/file.c
+++ b/security/apparmor/file.c
@@ -35,20 +35,6 @@
}
/**
- * audit_file_mask - convert mask to permission string
- * @buffer: buffer to write string to (NOT NULL)
- * @mask: permission mask to convert
- */
-static void audit_file_mask(struct audit_buffer *ab, u32 mask)
-{
- char str[10];
-
- aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
- map_mask_to_chr_mask(mask));
- audit_log_string(ab, str);
-}
-
-/**
* file_audit_cb - call back for file specific audit fields
* @ab: audit_buffer (NOT NULL)
* @va: audit struct to audit values of (NOT NULL)
@@ -57,14 +43,17 @@
{
struct common_audit_data *sa = va;
kuid_t fsuid = current_fsuid();
+ char str[10];
if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " requested_mask=");
- audit_file_mask(ab, aad(sa)->request);
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+ map_mask_to_chr_mask(aad(sa)->request));
+ audit_log_format(ab, " requested_mask=\"%s\"", str);
}
if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
- audit_log_format(ab, " denied_mask=");
- audit_file_mask(ab, aad(sa)->denied);
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
+ map_mask_to_chr_mask(aad(sa)->denied));
+ audit_log_format(ab, " denied_mask=\"%s\"", str);
}
if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
audit_log_format(ab, " fsuid=%d",
@@ -76,7 +65,7 @@
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);
@@ -154,13 +143,13 @@
* is_deleted - test if a file has been completely unlinked
* @dentry: dentry of file to test for deletion (NOT NULL)
*
- * Returns: %1 if deleted else %0
+ * Returns: true if deleted else false
*/
static inline bool is_deleted(struct dentry *dentry)
{
if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
- return 1;
- return 0;
+ return true;
+ return false;
}
static int path_name(const char *op, struct aa_label *label,
@@ -332,12 +321,14 @@
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;
}
@@ -351,15 +342,15 @@
* this is done as part of the subset test, where a hardlink must have
* a subset of permissions that the target has.
*
- * Returns: %1 if subset else %0
+ * Returns: true if subset else false
*/
static inline bool xindex_is_subset(u32 link, u32 target)
{
if (((link & ~AA_X_UNSAFE) != (target & ~AA_X_UNSAFE)) ||
((link & AA_X_UNSAFE) && !(target & AA_X_UNSAFE)))
- return 0;
+ return false;
- return 1;
+ return true;
}
static int profile_path_link(struct aa_profile *profile,
@@ -475,12 +466,18 @@
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;
}
@@ -507,7 +504,7 @@
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 = {};
@@ -524,7 +521,9 @@
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,
@@ -553,7 +552,7 @@
if (!error)
update_file_ctx(file_ctx(file), label, request);
- put_buffers(buffer);
+ aa_put_buffer(buffer);
return error;
}
@@ -590,11 +589,12 @@
* @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;
@@ -619,21 +619,25 @@
*/
denied = request & ~fctx->allow;
if (unconfined(label) || unconfined(flabel) ||
- (!denied && aa_label_is_subset(flabel, label)))
+ (!denied && aa_label_is_subset(flabel, label))) {
+ rcu_read_unlock();
goto done;
+ }
+ flabel = aa_get_newest_label(flabel);
+ rcu_read_unlock();
/* TODO: label cross check */
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);
+done:
return error;
}
@@ -655,7 +659,8 @@
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);
@@ -669,7 +674,8 @@
{
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;
}