hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/security/apparmor/file.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * AppArmor security module
34 *
....@@ -5,11 +6,6 @@
56 *
67 * Copyright (C) 1998-2008 Novell/SUSE
78 * Copyright 2009-2010 Canonical Ltd.
8
- *
9
- * This program is free software; you can redistribute it and/or
10
- * modify it under the terms of the GNU General Public License as
11
- * published by the Free Software Foundation, version 2 of the
12
- * License.
139 */
1410
1511 #include <linux/tty.h>
....@@ -39,20 +35,6 @@
3935 }
4036
4137 /**
42
- * audit_file_mask - convert mask to permission string
43
- * @buffer: buffer to write string to (NOT NULL)
44
- * @mask: permission mask to convert
45
- */
46
-static void audit_file_mask(struct audit_buffer *ab, u32 mask)
47
-{
48
- char str[10];
49
-
50
- aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
51
- map_mask_to_chr_mask(mask));
52
- audit_log_string(ab, str);
53
-}
54
-
55
-/**
5638 * file_audit_cb - call back for file specific audit fields
5739 * @ab: audit_buffer (NOT NULL)
5840 * @va: audit struct to audit values of (NOT NULL)
....@@ -61,14 +43,17 @@
6143 {
6244 struct common_audit_data *sa = va;
6345 kuid_t fsuid = current_fsuid();
46
+ char str[10];
6447
6548 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
66
- audit_log_format(ab, " requested_mask=");
67
- audit_file_mask(ab, aad(sa)->request);
49
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
50
+ map_mask_to_chr_mask(aad(sa)->request));
51
+ audit_log_format(ab, " requested_mask=\"%s\"", str);
6852 }
6953 if (aad(sa)->denied & AA_AUDIT_FILE_MASK) {
70
- audit_log_format(ab, " denied_mask=");
71
- audit_file_mask(ab, aad(sa)->denied);
54
+ aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs,
55
+ map_mask_to_chr_mask(aad(sa)->denied));
56
+ audit_log_format(ab, " denied_mask=\"%s\"", str);
7257 }
7358 if (aad(sa)->request & AA_AUDIT_FILE_MASK) {
7459 audit_log_format(ab, " fsuid=%d",
....@@ -80,7 +65,7 @@
8065 if (aad(sa)->peer) {
8166 audit_log_format(ab, " target=");
8267 aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer,
83
- FLAG_VIEW_SUBNS, GFP_ATOMIC);
68
+ FLAG_VIEW_SUBNS, GFP_KERNEL);
8469 } else if (aad(sa)->fs.target) {
8570 audit_log_format(ab, " target=");
8671 audit_log_untrustedstring(ab, aad(sa)->fs.target);
....@@ -158,13 +143,13 @@
158143 * is_deleted - test if a file has been completely unlinked
159144 * @dentry: dentry of file to test for deletion (NOT NULL)
160145 *
161
- * Returns: %1 if deleted else %0
146
+ * Returns: true if deleted else false
162147 */
163148 static inline bool is_deleted(struct dentry *dentry)
164149 {
165150 if (d_unlinked(dentry) && d_backing_inode(dentry)->i_nlink == 0)
166
- return 1;
167
- return 0;
151
+ return true;
152
+ return false;
168153 }
169154
170155 static int path_name(const char *op, struct aa_label *label,
....@@ -336,12 +321,14 @@
336321
337322 flags |= PATH_DELEGATE_DELETED | (S_ISDIR(cond->mode) ? PATH_IS_DIR :
338323 0);
339
- get_buffers(buffer);
324
+ buffer = aa_get_buffer(false);
325
+ if (!buffer)
326
+ return -ENOMEM;
340327 error = fn_for_each_confined(label, profile,
341328 profile_path_perm(op, profile, path, buffer, request,
342329 cond, flags, &perms));
343330
344
- put_buffers(buffer);
331
+ aa_put_buffer(buffer);
345332
346333 return error;
347334 }
....@@ -355,15 +342,15 @@
355342 * this is done as part of the subset test, where a hardlink must have
356343 * a subset of permissions that the target has.
357344 *
358
- * Returns: %1 if subset else %0
345
+ * Returns: true if subset else false
359346 */
360347 static inline bool xindex_is_subset(u32 link, u32 target)
361348 {
362349 if (((link & ~AA_X_UNSAFE) != (target & ~AA_X_UNSAFE)) ||
363350 ((link & AA_X_UNSAFE) && !(target & AA_X_UNSAFE)))
364
- return 0;
351
+ return false;
365352
366
- return 1;
353
+ return true;
367354 }
368355
369356 static int profile_path_link(struct aa_profile *profile,
....@@ -479,12 +466,18 @@
479466 int error;
480467
481468 /* buffer freed below, lname is pointer in buffer */
482
- get_buffers(buffer, buffer2);
469
+ buffer = aa_get_buffer(false);
470
+ buffer2 = aa_get_buffer(false);
471
+ error = -ENOMEM;
472
+ if (!buffer || !buffer2)
473
+ goto out;
474
+
483475 error = fn_for_each_confined(label, profile,
484476 profile_path_link(profile, &link, buffer, &target,
485477 buffer2, &cond));
486
- put_buffers(buffer, buffer2);
487
-
478
+out:
479
+ aa_put_buffer(buffer);
480
+ aa_put_buffer(buffer2);
488481 return error;
489482 }
490483
....@@ -496,7 +489,7 @@
496489 /* update caching of label on file_ctx */
497490 spin_lock(&fctx->lock);
498491 old = rcu_dereference_protected(fctx->label,
499
- spin_is_locked(&fctx->lock));
492
+ lockdep_is_held(&fctx->lock));
500493 l = aa_label_merge(old, label, GFP_ATOMIC);
501494 if (l) {
502495 if (l != old) {
....@@ -511,7 +504,7 @@
511504
512505 static int __file_path_perm(const char *op, struct aa_label *label,
513506 struct aa_label *flabel, struct file *file,
514
- u32 request, u32 denied)
507
+ u32 request, u32 denied, bool in_atomic)
515508 {
516509 struct aa_profile *profile;
517510 struct aa_perms perms = {};
....@@ -528,7 +521,9 @@
528521 return 0;
529522
530523 flags = PATH_DELEGATE_DELETED | (S_ISDIR(cond.mode) ? PATH_IS_DIR : 0);
531
- get_buffers(buffer);
524
+ buffer = aa_get_buffer(in_atomic);
525
+ if (!buffer)
526
+ return -ENOMEM;
532527
533528 /* check every profile in task label not in current cache */
534529 error = fn_for_each_not_in_set(flabel, label, profile,
....@@ -557,7 +552,7 @@
557552 if (!error)
558553 update_file_ctx(file_ctx(file), label, request);
559554
560
- put_buffers(buffer);
555
+ aa_put_buffer(buffer);
561556
562557 return error;
563558 }
....@@ -594,11 +589,12 @@
594589 * @label: label being enforced (NOT NULL)
595590 * @file: file to revalidate access permissions on (NOT NULL)
596591 * @request: requested permissions
592
+ * @in_atomic: whether allocations need to be done in atomic context
597593 *
598594 * Returns: %0 if access allowed else error
599595 */
600596 int aa_file_perm(const char *op, struct aa_label *label, struct file *file,
601
- u32 request)
597
+ u32 request, bool in_atomic)
602598 {
603599 struct aa_file_ctx *fctx;
604600 struct aa_label *flabel;
....@@ -623,21 +619,25 @@
623619 */
624620 denied = request & ~fctx->allow;
625621 if (unconfined(label) || unconfined(flabel) ||
626
- (!denied && aa_label_is_subset(flabel, label)))
622
+ (!denied && aa_label_is_subset(flabel, label))) {
623
+ rcu_read_unlock();
627624 goto done;
625
+ }
628626
627
+ flabel = aa_get_newest_label(flabel);
628
+ rcu_read_unlock();
629629 /* TODO: label cross check */
630630
631631 if (file->f_path.mnt && path_mediated_fs(file->f_path.dentry))
632632 error = __file_path_perm(op, label, flabel, file, request,
633
- denied);
633
+ denied, in_atomic);
634634
635635 else if (S_ISSOCK(file_inode(file)->i_mode))
636636 error = __file_sock_perm(op, label, flabel, file, request,
637637 denied);
638
-done:
639
- rcu_read_unlock();
638
+ aa_put_label(flabel);
640639
640
+done:
641641 return error;
642642 }
643643
....@@ -659,7 +659,8 @@
659659 struct tty_file_private, list);
660660 file = file_priv->file;
661661
662
- if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE))
662
+ if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE,
663
+ IN_ATOMIC))
663664 drop_tty = 1;
664665 }
665666 spin_unlock(&tty->files_lock);
....@@ -673,7 +674,8 @@
673674 {
674675 struct aa_label *label = (struct aa_label *)p;
675676
676
- if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file)))
677
+ if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file),
678
+ IN_ATOMIC))
677679 return fd + 1;
678680 return 0;
679681 }