Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

apparmor: make __begin_current_label_crit_section() indicate whether put is needed

Same as aa_get_newest_cred_label_condref().

This avoids a bunch of work overall and allows the compiler to note when no
clean up is necessary, allowing for tail calls.

This in particular happens in apparmor_file_permission(), which manages to
tail call aa_file_perm() 105 bytes in (vs a regular call 112 bytes in
followed by branches to figure out if clean up is needed).

Signed-off-by: Mateusz Guzik <mjguzik@gmail.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>

authored by

Mateusz Guzik and committed by
John Johansen
87cc7b00 37a3741d

+67 -41
+15 -6
security/apparmor/include/cred.h
··· 114 114 return aa_get_label(l); 115 115 } 116 116 117 - #define __end_current_label_crit_section(X) end_current_label_crit_section(X) 117 + static inline void __end_current_label_crit_section(struct aa_label *label, 118 + bool needput) 119 + { 120 + if (unlikely(needput)) 121 + aa_put_label(label); 122 + } 118 123 119 124 /** 120 125 * end_current_label_crit_section - put a reference found with begin_current_label.. ··· 147 142 * critical section between __begin_current_label_crit_section() .. 148 143 * __end_current_label_crit_section() 149 144 */ 150 - static inline struct aa_label *__begin_current_label_crit_section(void) 145 + static inline struct aa_label *__begin_current_label_crit_section(bool *needput) 151 146 { 152 147 struct aa_label *label = aa_current_raw_label(); 153 148 154 - if (label_is_stale(label)) 155 - label = aa_get_newest_label(label); 149 + if (label_is_stale(label)) { 150 + *needput = true; 151 + return aa_get_newest_label(label); 152 + } 156 153 154 + *needput = false; 157 155 return label; 158 156 } 159 157 ··· 192 184 { 193 185 struct aa_label *label; 194 186 struct aa_ns *ns; 187 + bool needput; 195 188 196 - label = __begin_current_label_crit_section(); 189 + label = __begin_current_label_crit_section(&needput); 197 190 ns = aa_get_ns(labels_ns(label)); 198 - __end_current_label_crit_section(label); 191 + __end_current_label_crit_section(label, needput); 199 192 200 193 return ns; 201 194 }
+46 -29
security/apparmor/lsm.c
··· 127 127 struct aa_label *tracer, *tracee; 128 128 const struct cred *cred; 129 129 int error; 130 + bool needput; 130 131 131 132 cred = get_task_cred(child); 132 133 tracee = cred_label(cred); /* ref count on cred */ 133 - tracer = __begin_current_label_crit_section(); 134 + tracer = __begin_current_label_crit_section(&needput); 134 135 error = aa_may_ptrace(current_cred(), tracer, cred, tracee, 135 136 (mode & PTRACE_MODE_READ) ? AA_PTRACE_READ 136 137 : AA_PTRACE_TRACE); 137 - __end_current_label_crit_section(tracer); 138 + __end_current_label_crit_section(tracer, needput); 138 139 put_cred(cred); 139 140 140 141 return error; ··· 146 145 struct aa_label *tracer, *tracee; 147 146 const struct cred *cred; 148 147 int error; 148 + bool needput; 149 149 150 - tracee = __begin_current_label_crit_section(); 150 + tracee = __begin_current_label_crit_section(&needput); 151 151 cred = get_task_cred(parent); 152 152 tracer = cred_label(cred); /* ref count on cred */ 153 153 error = aa_may_ptrace(cred, tracer, current_cred(), tracee, 154 154 AA_PTRACE_TRACE); 155 155 put_cred(cred); 156 - __end_current_label_crit_section(tracee); 156 + __end_current_label_crit_section(tracee, needput); 157 157 158 158 return error; 159 159 } ··· 223 221 { 224 222 struct aa_label *label; 225 223 int error = 0; 224 + bool needput; 226 225 227 - label = __begin_current_label_crit_section(); 226 + label = __begin_current_label_crit_section(&needput); 228 227 if (!unconfined(label)) 229 228 error = aa_path_perm(op, current_cred(), label, path, 0, mask, 230 229 cond); 231 - __end_current_label_crit_section(label); 230 + __end_current_label_crit_section(label, needput); 232 231 233 232 return error; 234 233 } ··· 527 524 { 528 525 struct aa_label *label; 529 526 int error = 0; 527 + bool needput; 530 528 531 529 /* don't reaudit files closed during inheritance */ 532 - if (file->f_path.dentry == aa_null.dentry) 530 + if (unlikely(file->f_path.dentry == aa_null.dentry)) 533 531 return -EACCES; 534 532 535 - label = __begin_current_label_crit_section(); 533 + label = __begin_current_label_crit_section(&needput); 536 534 error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic); 537 - __end_current_label_crit_section(label); 535 + __end_current_label_crit_section(label, needput); 538 536 539 537 return error; 540 538 } ··· 668 664 struct aa_profile *profile; 669 665 struct aa_label *label; 670 666 int error; 667 + bool needput; 671 668 DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_IO_URING, 672 669 OP_URING_OVERRIDE); 673 670 674 671 ad.uring.target = cred_label(new); 675 - label = __begin_current_label_crit_section(); 672 + label = __begin_current_label_crit_section(&needput); 676 673 error = fn_for_each(label, profile, 677 674 profile_uring(profile, AA_MAY_OVERRIDE_CRED, 678 675 cred_label(new), CAP_SYS_ADMIN, &ad)); 679 - __end_current_label_crit_section(label); 676 + __end_current_label_crit_section(label, needput); 680 677 681 678 return error; 682 679 } ··· 693 688 struct aa_profile *profile; 694 689 struct aa_label *label; 695 690 int error; 691 + bool needput; 696 692 DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_IO_URING, 697 693 OP_URING_SQPOLL); 698 694 699 - label = __begin_current_label_crit_section(); 695 + label = __begin_current_label_crit_section(&needput); 700 696 error = fn_for_each(label, profile, 701 697 profile_uring(profile, AA_MAY_CREATE_SQPOLL, 702 698 NULL, CAP_SYS_ADMIN, &ad)); 703 - __end_current_label_crit_section(label); 699 + __end_current_label_crit_section(label, needput); 704 700 705 701 return error; 706 702 } ··· 712 706 { 713 707 struct aa_label *label; 714 708 int error = 0; 709 + bool needput; 715 710 716 711 /* Discard magic */ 717 712 if ((flags & MS_MGC_MSK) == MS_MGC_VAL) ··· 720 713 721 714 flags &= ~AA_MS_IGNORE_MASK; 722 715 723 - label = __begin_current_label_crit_section(); 716 + label = __begin_current_label_crit_section(&needput); 724 717 if (!unconfined(label)) { 725 718 if (flags & MS_REMOUNT) 726 719 error = aa_remount(current_cred(), label, path, flags, ··· 739 732 error = aa_new_mount(current_cred(), label, dev_name, 740 733 path, type, flags, data); 741 734 } 742 - __end_current_label_crit_section(label); 735 + __end_current_label_crit_section(label, needput); 743 736 744 737 return error; 745 738 } ··· 749 742 { 750 743 struct aa_label *label; 751 744 int error = 0; 745 + bool needput; 752 746 753 - label = __begin_current_label_crit_section(); 747 + label = __begin_current_label_crit_section(&needput); 754 748 if (!unconfined(label)) 755 749 error = aa_move_mount(current_cred(), label, from_path, 756 750 to_path); 757 - __end_current_label_crit_section(label); 751 + __end_current_label_crit_section(label, needput); 758 752 759 753 return error; 760 754 } ··· 764 756 { 765 757 struct aa_label *label; 766 758 int error = 0; 759 + bool needput; 767 760 768 - label = __begin_current_label_crit_section(); 761 + label = __begin_current_label_crit_section(&needput); 769 762 if (!unconfined(label)) 770 763 error = aa_umount(current_cred(), label, mnt, flags); 771 - __end_current_label_crit_section(label); 764 + __end_current_label_crit_section(label, needput); 772 765 773 766 return error; 774 767 } ··· 993 984 994 985 static void apparmor_current_getlsmprop_subj(struct lsm_prop *prop) 995 986 { 996 - struct aa_label *label = __begin_current_label_crit_section(); 987 + struct aa_label *label; 988 + bool needput; 997 989 990 + label = __begin_current_label_crit_section(&needput); 998 991 prop->apparmor.label = label; 999 - __end_current_label_crit_section(label); 992 + __end_current_label_crit_section(label, needput); 1000 993 } 1001 994 1002 995 static void apparmor_task_getlsmprop_obj(struct task_struct *p, ··· 1013 1002 static int apparmor_task_setrlimit(struct task_struct *task, 1014 1003 unsigned int resource, struct rlimit *new_rlim) 1015 1004 { 1016 - struct aa_label *label = __begin_current_label_crit_section(); 1005 + struct aa_label *label; 1017 1006 int error = 0; 1007 + bool needput; 1008 + 1009 + label = __begin_current_label_crit_section(&needput); 1018 1010 1019 1011 if (!unconfined(label)) 1020 1012 error = aa_task_setrlimit(current_cred(), label, task, 1021 1013 resource, new_rlim); 1022 - __end_current_label_crit_section(label); 1014 + __end_current_label_crit_section(label, needput); 1023 1015 1024 1016 return error; 1025 1017 } ··· 1033 1019 const struct cred *tc; 1034 1020 struct aa_label *cl, *tl; 1035 1021 int error; 1022 + bool needput; 1036 1023 1037 1024 tc = get_task_cred(target); 1038 1025 tl = aa_get_newest_cred_label(tc); ··· 1045 1030 error = aa_may_signal(cred, cl, tc, tl, sig); 1046 1031 aa_put_label(cl); 1047 1032 } else { 1048 - cl = __begin_current_label_crit_section(); 1033 + cl = __begin_current_label_crit_section(&needput); 1049 1034 error = aa_may_signal(current_cred(), cl, tc, tl, sig); 1050 - __end_current_label_crit_section(cl); 1035 + __end_current_label_crit_section(cl, needput); 1051 1036 } 1052 1037 aa_put_label(tl); 1053 1038 put_cred(tc); ··· 1148 1133 struct aa_sk_ctx *new_ctx = aa_sock(newsk); 1149 1134 struct aa_label *label; 1150 1135 int error; 1136 + bool needput; 1151 1137 1152 - label = __begin_current_label_crit_section(); 1138 + label = __begin_current_label_crit_section(&needput); 1153 1139 error = unix_connect_perm(current_cred(), label, sk, peer_sk); 1154 - __end_current_label_crit_section(label); 1140 + __end_current_label_crit_section(label, needput); 1155 1141 1156 1142 if (error) 1157 1143 return error; ··· 1179 1163 struct aa_sk_ctx *peer_ctx = aa_sock(peer->sk); 1180 1164 struct aa_label *label; 1181 1165 int error; 1166 + bool needput; 1182 1167 1183 - label = __begin_current_label_crit_section(); 1168 + label = __begin_current_label_crit_section(&needput); 1184 1169 error = xcheck(aa_unix_peer_perm(current_cred(), 1185 1170 label, OP_SENDMSG, AA_MAY_SEND, 1186 1171 sock->sk, peer->sk, NULL), ··· 1189 1172 peer_ctx->label, OP_SENDMSG, 1190 1173 AA_MAY_RECEIVE, 1191 1174 peer->sk, sock->sk, label)); 1192 - __end_current_label_crit_section(label); 1175 + __end_current_label_crit_section(label, needput); 1193 1176 1194 1177 return error; 1195 1178 }
+6 -6
security/apparmor/policy.c
··· 870 870 bool aa_current_policy_view_capable(struct aa_ns *ns) 871 871 { 872 872 struct aa_label *label; 873 - bool res; 873 + bool needput, res; 874 874 875 - label = __begin_current_label_crit_section(); 875 + label = __begin_current_label_crit_section(&needput); 876 876 res = aa_policy_view_capable(current_cred(), label, ns); 877 - __end_current_label_crit_section(label); 877 + __end_current_label_crit_section(label, needput); 878 878 879 879 return res; 880 880 } ··· 882 882 bool aa_current_policy_admin_capable(struct aa_ns *ns) 883 883 { 884 884 struct aa_label *label; 885 - bool res; 885 + bool needput, res; 886 886 887 - label = __begin_current_label_crit_section(); 887 + label = __begin_current_label_crit_section(&needput); 888 888 res = aa_policy_admin_capable(current_cred(), label, ns); 889 - __end_current_label_crit_section(label); 889 + __end_current_label_crit_section(label, needput); 890 890 891 891 return res; 892 892 }