From: Sasha Levin Date: Fri, 24 Nov 2023 04:28:38 +0000 (-0500) Subject: Fixes for 6.6 X-Git-Tag: v4.14.331~79^2~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0f56330d888fce0c2b09eb57832fbb41bc077764;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 6.6 Signed-off-by: Sasha Levin --- diff --git a/queue-6.6/apparmor-combine-common_audit_data-and-apparmor_audi.patch b/queue-6.6/apparmor-combine-common_audit_data-and-apparmor_audi.patch new file mode 100644 index 00000000000..ded3f81fab1 --- /dev/null +++ b/queue-6.6/apparmor-combine-common_audit_data-and-apparmor_audi.patch @@ -0,0 +1,1183 @@ +From bf8c7a978ba2ae5754a2d81f3137492066926f0e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 14 Sep 2022 00:20:12 -0700 +Subject: apparmor: combine common_audit_data and apparmor_audit_data + +From: John Johansen + +[ Upstream commit bd7bd201ca46c211c3ab251ca9854787d1331a2f ] + +Everywhere where common_audit_data is used apparmor audit_data is also +used. We can simplify the code and drop the use of the aad macro +everywhere by combining the two structures. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation") +Signed-off-by: Sasha Levin +--- + security/apparmor/audit.c | 70 +++++++++++++++---------------- + security/apparmor/capability.c | 24 +++++------ + security/apparmor/file.c | 68 +++++++++++++++--------------- + security/apparmor/include/audit.h | 34 ++++++++------- + security/apparmor/include/net.h | 13 +++--- + security/apparmor/include/perms.h | 4 +- + security/apparmor/ipc.c | 39 ++++++++--------- + security/apparmor/lib.c | 47 +++++++++++---------- + security/apparmor/lsm.c | 12 +++--- + security/apparmor/mount.c | 41 +++++++++--------- + security/apparmor/net.c | 44 +++++++++---------- + security/apparmor/policy.c | 19 +++++---- + security/apparmor/policy_unpack.c | 29 ++++++------- + security/apparmor/resource.c | 23 +++++----- + security/apparmor/task.c | 35 ++++++++-------- + 15 files changed, 257 insertions(+), 245 deletions(-) + +diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c +index a3db0f8bd4f85..06ad6a8fcce18 100644 +--- a/security/apparmor/audit.c ++++ b/security/apparmor/audit.c +@@ -85,37 +85,36 @@ static const char *const aa_class_names[] = { + /** + * audit_pre() - core AppArmor function. + * @ab: audit buffer to fill (NOT NULL) +- * @ca: audit structure containing data to audit (NOT NULL) ++ * @va: audit structure containing data to audit (NOT NULL) + * +- * Record common AppArmor audit data from @sa ++ * Record common AppArmor audit data from @va + */ +-static void audit_pre(struct audit_buffer *ab, void *ca) ++static void audit_pre(struct audit_buffer *ab, void *va) + { +- struct common_audit_data *sa = ca; ++ struct apparmor_audit_data *ad = aad_of_va(va); + + if (aa_g_audit_header) { + audit_log_format(ab, "apparmor=\"%s\"", +- aa_audit_type[aad(sa)->type]); ++ aa_audit_type[ad->type]); + } + +- if (aad(sa)->op) { +- audit_log_format(ab, " operation=\"%s\"", aad(sa)->op); +- } ++ if (ad->op) ++ audit_log_format(ab, " operation=\"%s\"", ad->op); + +- if (aad(sa)->class) ++ if (ad->class) + audit_log_format(ab, " class=\"%s\"", +- aad(sa)->class <= AA_CLASS_LAST ? +- aa_class_names[aad(sa)->class] : ++ ad->class <= AA_CLASS_LAST ? ++ aa_class_names[ad->class] : + "unknown"); + +- if (aad(sa)->info) { +- audit_log_format(ab, " info=\"%s\"", aad(sa)->info); +- if (aad(sa)->error) +- audit_log_format(ab, " error=%d", aad(sa)->error); ++ if (ad->info) { ++ audit_log_format(ab, " info=\"%s\"", ad->info); ++ if (ad->error) ++ audit_log_format(ab, " error=%d", ad->error); + } + +- if (aad(sa)->label) { +- struct aa_label *label = aad(sa)->label; ++ if (ad->label) { ++ struct aa_label *label = ad->label; + + if (label_isprofile(label)) { + struct aa_profile *profile = labels_profile(label); +@@ -134,43 +133,44 @@ static void audit_pre(struct audit_buffer *ab, void *ca) + } + } + +- if (aad(sa)->name) { ++ if (ad->name) { + audit_log_format(ab, " name="); +- audit_log_untrustedstring(ab, aad(sa)->name); ++ audit_log_untrustedstring(ab, ad->name); + } + } + + /** + * aa_audit_msg - Log a message to the audit subsystem + * @type: audit type for the message +- * @sa: audit event structure (NOT NULL) ++ * @ad: audit event structure (NOT NULL) + * @cb: optional callback fn for type specific fields (MAYBE NULL) + */ +-void aa_audit_msg(int type, struct common_audit_data *sa, ++void aa_audit_msg(int type, struct apparmor_audit_data *ad, + void (*cb) (struct audit_buffer *, void *)) + { +- aad(sa)->type = type; +- common_lsm_audit(sa, audit_pre, cb); ++ ad->type = type; ++ common_lsm_audit(&ad->common, audit_pre, cb); + } + + /** + * aa_audit - Log a profile based audit event to the audit subsystem + * @type: audit type for the message + * @profile: profile to check against (NOT NULL) +- * @sa: audit event (NOT NULL) ++ * @ad: audit event (NOT NULL) + * @cb: optional callback fn for type specific fields (MAYBE NULL) + * + * Handle default message switching based off of audit mode flags + * + * Returns: error on failure + */ +-int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa, ++int aa_audit(int type, struct aa_profile *profile, ++ struct apparmor_audit_data *ad, + void (*cb) (struct audit_buffer *, void *)) + { + AA_BUG(!profile); + + if (type == AUDIT_APPARMOR_AUTO) { +- if (likely(!aad(sa)->error)) { ++ if (likely(!ad->error)) { + if (AUDIT_MODE(profile) != AUDIT_ALL) + return 0; + type = AUDIT_APPARMOR_AUDIT; +@@ -182,24 +182,24 @@ int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa, + if (AUDIT_MODE(profile) == AUDIT_QUIET || + (type == AUDIT_APPARMOR_DENIED && + AUDIT_MODE(profile) == AUDIT_QUIET_DENIED)) +- return aad(sa)->error; ++ return ad->error; + + if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) + type = AUDIT_APPARMOR_KILL; + +- aad(sa)->label = &profile->label; ++ ad->label = &profile->label; + +- aa_audit_msg(type, sa, cb); ++ aa_audit_msg(type, ad, cb); + +- if (aad(sa)->type == AUDIT_APPARMOR_KILL) ++ if (ad->type == AUDIT_APPARMOR_KILL) + (void)send_sig_info(SIGKILL, NULL, +- sa->type == LSM_AUDIT_DATA_TASK && sa->u.tsk ? +- sa->u.tsk : current); ++ ad->common.type == LSM_AUDIT_DATA_TASK && ++ ad->common.u.tsk ? ad->common.u.tsk : current); + +- if (aad(sa)->type == AUDIT_APPARMOR_ALLOWED) +- return complain_error(aad(sa)->error); ++ if (ad->type == AUDIT_APPARMOR_ALLOWED) ++ return complain_error(ad->error); + +- return aad(sa)->error; ++ return ad->error; + } + + struct aa_audit_rule { +diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c +index 326a51838ef28..58490cca035da 100644 +--- a/security/apparmor/capability.c ++++ b/security/apparmor/capability.c +@@ -51,7 +51,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) + + /** + * audit_caps - audit a capability +- * @sa: audit data ++ * @as: audit data + * @profile: profile being tested for confinement (NOT NULL) + * @cap: capability tested + * @error: error code returned by test +@@ -59,9 +59,9 @@ static void audit_cb(struct audit_buffer *ab, void *va) + * Do auditing of capability and handle, audit/complain/kill modes switching + * and duplicate message elimination. + * +- * Returns: 0 or sa->error on success, error code on failure ++ * Returns: 0 or ad->error on success, error code on failure + */ +-static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile, ++static int audit_caps(struct apparmor_audit_data *ad, struct aa_profile *profile, + int cap, int error) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, +@@ -69,7 +69,7 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile, + struct audit_cache *ent; + int type = AUDIT_APPARMOR_AUTO; + +- aad(sa)->error = error; ++ ad->error = error; + + if (likely(!error)) { + /* test if auditing is being forced */ +@@ -101,7 +101,7 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile, + } + put_cpu_var(audit_cache); + +- return aa_audit(type, profile, sa, audit_cb); ++ return aa_audit(type, profile, ad, audit_cb); + } + + /** +@@ -109,12 +109,12 @@ static int audit_caps(struct common_audit_data *sa, struct aa_profile *profile, + * @profile: profile being enforced (NOT NULL, NOT unconfined) + * @cap: capability to test if allowed + * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated +- * @sa: audit data (MAY BE NULL indicating no auditing) ++ * @ad: audit data (MAY BE NULL indicating no auditing) + * + * Returns: 0 if allowed else -EPERM + */ + static int profile_capable(struct aa_profile *profile, int cap, +- unsigned int opts, struct common_audit_data *sa) ++ unsigned int opts, struct apparmor_audit_data *ad) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, + typeof(*rules), list); +@@ -132,10 +132,10 @@ static int profile_capable(struct aa_profile *profile, int cap, + /* audit the cap request in complain mode but note that it + * should be optional. + */ +- aad(sa)->info = "optional: no audit"; ++ ad->info = "optional: no audit"; + } + +- return audit_caps(sa, profile, cap, error); ++ return audit_caps(ad, profile, cap, error); + } + + /** +@@ -152,11 +152,11 @@ int aa_capable(struct aa_label *label, int cap, unsigned int opts) + { + struct aa_profile *profile; + int error = 0; +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_CAP, AA_CLASS_CAP, OP_CAPABLE); ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_CAP, AA_CLASS_CAP, OP_CAPABLE); + +- sa.u.cap = cap; ++ ad.common.u.cap = cap; + error = fn_for_each_confined(label, profile, +- profile_capable(profile, cap, opts, &sa)); ++ profile_capable(profile, cap, opts, &ad)); + + return error; + } +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index 698b124e649f6..9ea95fa18e7d5 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -44,33 +44,34 @@ static u32 map_mask_to_chr_mask(u32 mask) + static void file_audit_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + kuid_t fsuid = current_fsuid(); + char str[10]; + +- if (aad(sa)->request & AA_AUDIT_FILE_MASK) { ++ if (ad->request & AA_AUDIT_FILE_MASK) { + aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs, +- map_mask_to_chr_mask(aad(sa)->request)); ++ map_mask_to_chr_mask(ad->request)); + audit_log_format(ab, " requested_mask=\"%s\"", str); + } +- if (aad(sa)->denied & AA_AUDIT_FILE_MASK) { ++ if (ad->denied & AA_AUDIT_FILE_MASK) { + aa_perm_mask_to_str(str, sizeof(str), aa_file_perm_chrs, +- map_mask_to_chr_mask(aad(sa)->denied)); ++ map_mask_to_chr_mask(ad->denied)); + audit_log_format(ab, " denied_mask=\"%s\"", str); + } +- if (aad(sa)->request & AA_AUDIT_FILE_MASK) { ++ if (ad->request & AA_AUDIT_FILE_MASK) { + audit_log_format(ab, " fsuid=%d", + from_kuid(&init_user_ns, fsuid)); + audit_log_format(ab, " ouid=%d", +- from_kuid(&init_user_ns, aad(sa)->fs.ouid)); ++ from_kuid(&init_user_ns, ad->fs.ouid)); + } + +- if (aad(sa)->peer) { ++ if (ad->peer) { + audit_log_format(ab, " target="); +- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, ++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, + FLAG_VIEW_SUBNS, GFP_KERNEL); +- } else if (aad(sa)->fs.target) { ++ } else if (ad->fs.target) { + audit_log_format(ab, " target="); +- audit_log_untrustedstring(ab, aad(sa)->fs.target); ++ audit_log_untrustedstring(ab, ad->fs.target); + } + } + +@@ -95,50 +96,49 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms, + kuid_t ouid, const char *info, int error) + { + int type = AUDIT_APPARMOR_AUTO; +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_TASK, AA_CLASS_FILE, op); +- +- sa.u.tsk = NULL; +- aad(&sa)->request = request; +- aad(&sa)->name = name; +- aad(&sa)->fs.target = target; +- aad(&sa)->peer = tlabel; +- aad(&sa)->fs.ouid = ouid; +- aad(&sa)->info = info; +- aad(&sa)->error = error; +- sa.u.tsk = NULL; +- +- if (likely(!aad(&sa)->error)) { ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_TASK, AA_CLASS_FILE, op); ++ ++ ad.request = request; ++ ad.name = name; ++ ad.fs.target = target; ++ ad.peer = tlabel; ++ ad.fs.ouid = ouid; ++ ad.info = info; ++ ad.error = error; ++ ad.common.u.tsk = NULL; ++ ++ if (likely(!ad.error)) { + u32 mask = perms->audit; + + if (unlikely(AUDIT_MODE(profile) == AUDIT_ALL)) + mask = 0xffff; + + /* mask off perms that are not being force audited */ +- aad(&sa)->request &= mask; ++ ad.request &= mask; + +- if (likely(!aad(&sa)->request)) ++ if (likely(!ad.request)) + return 0; + type = AUDIT_APPARMOR_AUDIT; + } else { + /* only report permissions that were denied */ +- aad(&sa)->request = aad(&sa)->request & ~perms->allow; +- AA_BUG(!aad(&sa)->request); ++ ad.request = ad.request & ~perms->allow; ++ AA_BUG(!ad.request); + +- if (aad(&sa)->request & perms->kill) ++ if (ad.request & perms->kill) + type = AUDIT_APPARMOR_KILL; + + /* quiet known rejects, assumes quiet and kill do not overlap */ +- if ((aad(&sa)->request & perms->quiet) && ++ if ((ad.request & perms->quiet) && + AUDIT_MODE(profile) != AUDIT_NOQUIET && + AUDIT_MODE(profile) != AUDIT_ALL) +- aad(&sa)->request &= ~perms->quiet; ++ ad.request &= ~perms->quiet; + +- if (!aad(&sa)->request) +- return aad(&sa)->error; ++ if (!ad.request) ++ return ad.error; + } + +- aad(&sa)->denied = aad(&sa)->request & ~perms->allow; +- return aa_audit(type, profile, &sa, file_audit_cb); ++ ad.denied = ad.request & ~perms->allow; ++ return aa_audit(type, profile, &ad, file_audit_cb); + } + + static int path_name(const char *op, struct aa_label *label, +diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h +index c328f07f11cd8..85931ec94e916 100644 +--- a/security/apparmor/include/audit.h ++++ b/security/apparmor/include/audit.h +@@ -152,33 +152,35 @@ struct apparmor_audit_data { + unsigned long flags; + } mnt; + }; ++ ++ struct common_audit_data common; + }; + + /* macros for dealing with apparmor_audit_data structure */ +-#define aad(SA) ((SA)->apparmor_audit_data) ++#define aad(SA) (container_of(SA, struct apparmor_audit_data, common)) ++#define aad_of_va(VA) aad((struct common_audit_data *)(VA)) ++ + #define DEFINE_AUDIT_DATA(NAME, T, C, X) \ + /* TODO: cleanup audit init so we don't need _aad = {0,} */ \ +- struct apparmor_audit_data NAME ## _aad = { \ ++ struct apparmor_audit_data NAME = { \ + .class = (C), \ + .op = (X), \ +- }; \ +- struct common_audit_data NAME = \ +- { \ +- .type = (T), \ +- .u.tsk = NULL, \ +- }; \ +- NAME.apparmor_audit_data = &(NAME ## _aad) +- +-void aa_audit_msg(int type, struct common_audit_data *sa, ++ .common.type = (T), \ ++ .common.u.tsk = NULL, \ ++ .common.apparmor_audit_data = &NAME, \ ++ }; ++ ++void aa_audit_msg(int type, struct apparmor_audit_data *ad, + void (*cb) (struct audit_buffer *, void *)); +-int aa_audit(int type, struct aa_profile *profile, struct common_audit_data *sa, ++int aa_audit(int type, struct aa_profile *profile, ++ struct apparmor_audit_data *ad, + void (*cb) (struct audit_buffer *, void *)); + +-#define aa_audit_error(ERROR, SA, CB) \ ++#define aa_audit_error(ERROR, AD, CB) \ + ({ \ +- aad((SA))->error = (ERROR); \ +- aa_audit_msg(AUDIT_APPARMOR_ERROR, (SA), (CB)); \ +- aad((SA))->error; \ ++ (AD)->error = (ERROR); \ ++ aa_audit_msg(AUDIT_APPARMOR_ERROR, (AD), (CB)); \ ++ (AD)->error; \ + }) + + +diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h +index 6fa440b5daed8..a336e57864e89 100644 +--- a/security/apparmor/include/net.h ++++ b/security/apparmor/include/net.h +@@ -61,9 +61,9 @@ struct aa_sk_ctx { + LSM_AUDIT_DATA_NONE, \ + AA_CLASS_NET, \ + OP); \ +- NAME.u.net = &(NAME ## _net); \ +- aad(&NAME)->net.type = (T); \ +- aad(&NAME)->net.protocol = (P) ++ NAME.common.u.net = &(NAME ## _net); \ ++ NAME.net.type = (T); \ ++ NAME.net.protocol = (P) + + #define DEFINE_AUDIT_SK(NAME, OP, SK) \ + DEFINE_AUDIT_NET(NAME, OP, SK, (SK)->sk_family, (SK)->sk_type, \ +@@ -90,16 +90,17 @@ struct aa_secmark { + extern struct aa_sfs_entry aa_sfs_entry_network[]; + + void audit_net_cb(struct audit_buffer *ab, void *va); +-int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, ++int aa_profile_af_perm(struct aa_profile *profile, ++ struct apparmor_audit_data *ad, + u32 request, u16 family, int type); + int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, + int type, int protocol); + static inline int aa_profile_af_sk_perm(struct aa_profile *profile, +- struct common_audit_data *sa, ++ struct apparmor_audit_data *ad, + u32 request, + struct sock *sk) + { +- return aa_profile_af_perm(profile, sa, request, sk->sk_family, ++ return aa_profile_af_perm(profile, ad, request, sk->sk_family, + sk->sk_type); + } + int aa_sk_perm(const char *op, u32 request, struct sock *sk); +diff --git a/security/apparmor/include/perms.h b/security/apparmor/include/perms.h +index 797a7a00644d2..83534df8939fd 100644 +--- a/security/apparmor/include/perms.h ++++ b/security/apparmor/include/perms.h +@@ -212,8 +212,8 @@ void aa_profile_match_label(struct aa_profile *profile, + int type, u32 request, struct aa_perms *perms); + int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, + u32 request, int type, u32 *deny, +- struct common_audit_data *sa); ++ struct apparmor_audit_data *ad); + int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms, +- u32 request, struct common_audit_data *sa, ++ u32 request, struct apparmor_audit_data *ad, + void (*cb)(struct audit_buffer *, void *)); + #endif /* __AA_PERM_H */ +diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c +index 5acde746775f7..f198b8d620a4f 100644 +--- a/security/apparmor/ipc.c ++++ b/security/apparmor/ipc.c +@@ -52,31 +52,32 @@ static const char *audit_signal_mask(u32 mask) + static void audit_signal_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + +- if (aad(sa)->request & AA_SIGNAL_PERM_MASK) { ++ if (ad->request & AA_SIGNAL_PERM_MASK) { + audit_log_format(ab, " requested_mask=\"%s\"", +- audit_signal_mask(aad(sa)->request)); +- if (aad(sa)->denied & AA_SIGNAL_PERM_MASK) { ++ audit_signal_mask(ad->request)); ++ if (ad->denied & AA_SIGNAL_PERM_MASK) { + audit_log_format(ab, " denied_mask=\"%s\"", +- audit_signal_mask(aad(sa)->denied)); ++ audit_signal_mask(ad->denied)); + } + } +- if (aad(sa)->signal == SIGUNKNOWN) ++ if (ad->signal == SIGUNKNOWN) + audit_log_format(ab, "signal=unknown(%d)", +- aad(sa)->unmappedsig); +- else if (aad(sa)->signal < MAXMAPPED_SIGNAME) +- audit_log_format(ab, " signal=%s", sig_names[aad(sa)->signal]); ++ ad->unmappedsig); ++ else if (ad->signal < MAXMAPPED_SIGNAME) ++ audit_log_format(ab, " signal=%s", sig_names[ad->signal]); + else + audit_log_format(ab, " signal=rtmin+%d", +- aad(sa)->signal - SIGRT_BASE); ++ ad->signal - SIGRT_BASE); + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, ++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + + static int profile_signal_perm(struct aa_profile *profile, + struct aa_label *peer, u32 request, +- struct common_audit_data *sa) ++ struct apparmor_audit_data *ad) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, + typeof(*rules), list); +@@ -87,24 +88,24 @@ static int profile_signal_perm(struct aa_profile *profile, + !ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_SIGNAL)) + return 0; + +- aad(sa)->peer = peer; ++ ad->peer = peer; + /* TODO: secondary cache check */ + state = aa_dfa_next(rules->policy.dfa, + rules->policy.start[AA_CLASS_SIGNAL], +- aad(sa)->signal); ++ ad->signal); + aa_label_match(profile, rules, peer, state, false, request, &perms); + aa_apply_modes_to_perms(profile, &perms); +- return aa_check_perms(profile, &perms, request, sa, audit_signal_cb); ++ return aa_check_perms(profile, &perms, request, ad, audit_signal_cb); + } + + int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig) + { + struct aa_profile *profile; +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_SIGNAL, OP_SIGNAL); ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_SIGNAL, OP_SIGNAL); + +- aad(&sa)->signal = map_signal_num(sig); +- aad(&sa)->unmappedsig = sig; ++ ad.signal = map_signal_num(sig); ++ ad.unmappedsig = sig; + return xcheck_labels(sender, target, profile, +- profile_signal_perm(profile, target, MAY_WRITE, &sa), +- profile_signal_perm(profile, sender, MAY_READ, &sa)); ++ profile_signal_perm(profile, target, MAY_WRITE, &ad), ++ profile_signal_perm(profile, sender, MAY_READ, &ad)); + } +diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c +index 8e1073477c096..d6b2750fd72e4 100644 +--- a/security/apparmor/lib.c ++++ b/security/apparmor/lib.c +@@ -144,10 +144,10 @@ const char *aa_splitn_fqname(const char *fqname, size_t n, const char **ns_name, + void aa_info_message(const char *str) + { + if (audit_enabled) { +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL); ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL); + +- aad(&sa)->info = str; +- aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, NULL); ++ ad.info = str; ++ aa_audit_msg(AUDIT_APPARMOR_STATUS, &ad, NULL); + } + printk(KERN_INFO "AppArmor: %s\n", str); + } +@@ -282,21 +282,22 @@ void aa_audit_perm_mask(struct audit_buffer *ab, u32 mask, const char *chrs, + static void aa_audit_perms_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + +- if (aad(sa)->request) { ++ if (ad->request) { + audit_log_format(ab, " requested_mask="); +- aa_audit_perm_mask(ab, aad(sa)->request, aa_file_perm_chrs, ++ aa_audit_perm_mask(ab, ad->request, aa_file_perm_chrs, + PERMS_CHRS_MASK, aa_file_perm_names, + PERMS_NAMES_MASK); + } +- if (aad(sa)->denied) { ++ if (ad->denied) { + audit_log_format(ab, "denied_mask="); +- aa_audit_perm_mask(ab, aad(sa)->denied, aa_file_perm_chrs, ++ aa_audit_perm_mask(ab, ad->denied, aa_file_perm_chrs, + PERMS_CHRS_MASK, aa_file_perm_names, + PERMS_NAMES_MASK); + } + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, ++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + +@@ -350,21 +351,21 @@ void aa_profile_match_label(struct aa_profile *profile, + /* currently unused */ + int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, + u32 request, int type, u32 *deny, +- struct common_audit_data *sa) ++ struct apparmor_audit_data *ad) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, + typeof(*rules), list); + struct aa_perms perms; + +- aad(sa)->label = &profile->label; +- aad(sa)->peer = &target->label; +- aad(sa)->request = request; ++ ad->label = &profile->label; ++ ad->peer = &target->label; ++ ad->request = request; + + aa_profile_match_label(profile, rules, &target->label, type, request, + &perms); + aa_apply_modes_to_perms(profile, &perms); + *deny |= request & perms.deny; +- return aa_check_perms(profile, &perms, request, sa, aa_audit_perms_cb); ++ return aa_check_perms(profile, &perms, request, ad, aa_audit_perms_cb); + } + + /** +@@ -372,7 +373,7 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, + * @profile: profile being checked + * @perms: perms computed for the request + * @request: requested perms +- * @sa: initialized audit structure (MAY BE NULL if not auditing) ++ * @ad: initialized audit structure (MAY BE NULL if not auditing) + * @cb: callback fn for type specific fields (MAY BE NULL) + * + * Returns: 0 if permission else error code +@@ -385,7 +386,7 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, + * with a positive value. + */ + int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms, +- u32 request, struct common_audit_data *sa, ++ u32 request, struct apparmor_audit_data *ad, + void (*cb)(struct audit_buffer *, void *)) + { + int type, error; +@@ -394,7 +395,7 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms, + if (likely(!denied)) { + /* mask off perms that are not being force audited */ + request &= perms->audit; +- if (!request || !sa) ++ if (!request || !ad) + return 0; + + type = AUDIT_APPARMOR_AUDIT; +@@ -413,16 +414,16 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms, + error = -ENOENT; + + denied &= ~perms->quiet; +- if (!sa || !denied) ++ if (!ad || !denied) + return error; + } + +- if (sa) { +- aad(sa)->label = &profile->label; +- aad(sa)->request = request; +- aad(sa)->denied = denied; +- aad(sa)->error = error; +- aa_audit_msg(type, sa, cb); ++ if (ad) { ++ ad->label = &profile->label; ++ ad->request = request; ++ ad->denied = denied; ++ ad->error = error; ++ aa_audit_msg(type, ad, cb); + } + + if (type == AUDIT_APPARMOR_ALLOWED) +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 108eccc5ada58..fd7852a4737c7 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -662,7 +662,7 @@ static int apparmor_setprocattr(const char *name, void *value, + char *command, *largs = NULL, *args = value; + size_t arg_size; + int error; +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, + OP_SETPROCATTR); + + if (size == 0) +@@ -722,11 +722,11 @@ static int apparmor_setprocattr(const char *name, void *value, + return error; + + fail: +- aad(&sa)->label = begin_current_label_crit_section(); +- aad(&sa)->info = name; +- aad(&sa)->error = error = -EINVAL; +- aa_audit_msg(AUDIT_APPARMOR_DENIED, &sa, NULL); +- end_current_label_crit_section(aad(&sa)->label); ++ ad.label = begin_current_label_crit_section(); ++ ad.info = name; ++ ad.error = error = -EINVAL; ++ aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL); ++ end_current_label_crit_section(ad.label); + goto out; + } + +diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c +index cdfa430ae2161..3830bceff9c8b 100644 +--- a/security/apparmor/mount.c ++++ b/security/apparmor/mount.c +@@ -86,27 +86,28 @@ static void audit_mnt_flags(struct audit_buffer *ab, unsigned long flags) + static void audit_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + +- if (aad(sa)->mnt.type) { ++ if (ad->mnt.type) { + audit_log_format(ab, " fstype="); +- audit_log_untrustedstring(ab, aad(sa)->mnt.type); ++ audit_log_untrustedstring(ab, ad->mnt.type); + } +- if (aad(sa)->mnt.src_name) { ++ if (ad->mnt.src_name) { + audit_log_format(ab, " srcname="); +- audit_log_untrustedstring(ab, aad(sa)->mnt.src_name); ++ audit_log_untrustedstring(ab, ad->mnt.src_name); + } +- if (aad(sa)->mnt.trans) { ++ if (ad->mnt.trans) { + audit_log_format(ab, " trans="); +- audit_log_untrustedstring(ab, aad(sa)->mnt.trans); ++ audit_log_untrustedstring(ab, ad->mnt.trans); + } +- if (aad(sa)->mnt.flags) { ++ if (ad->mnt.flags) { + audit_log_format(ab, " flags=\""); +- audit_mnt_flags(ab, aad(sa)->mnt.flags); ++ audit_mnt_flags(ab, ad->mnt.flags); + audit_log_format(ab, "\""); + } +- if (aad(sa)->mnt.data) { ++ if (ad->mnt.data) { + audit_log_format(ab, " options="); +- audit_log_untrustedstring(ab, aad(sa)->mnt.data); ++ audit_log_untrustedstring(ab, ad->mnt.data); + } + } + +@@ -134,7 +135,7 @@ static int audit_mount(struct aa_profile *profile, const char *op, + struct aa_perms *perms, const char *info, int error) + { + int audit_type = AUDIT_APPARMOR_AUTO; +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_MOUNT, op); ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_MOUNT, op); + + if (likely(!error)) { + u32 mask = perms->audit; +@@ -165,17 +166,17 @@ static int audit_mount(struct aa_profile *profile, const char *op, + return error; + } + +- aad(&sa)->name = name; +- aad(&sa)->mnt.src_name = src_name; +- aad(&sa)->mnt.type = type; +- aad(&sa)->mnt.trans = trans; +- aad(&sa)->mnt.flags = flags; ++ ad.name = name; ++ ad.mnt.src_name = src_name; ++ ad.mnt.type = type; ++ ad.mnt.trans = trans; ++ ad.mnt.flags = flags; + if (data && (perms->audit & AA_AUDIT_DATA)) +- aad(&sa)->mnt.data = data; +- aad(&sa)->info = info; +- aad(&sa)->error = error; ++ ad.mnt.data = data; ++ ad.info = info; ++ ad.error = error; + +- return aa_audit(audit_type, profile, &sa, audit_cb); ++ return aa_audit(audit_type, profile, &ad, audit_cb); + } + + /** +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 788be1609a865..0c7304cd479c5 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -71,6 +71,7 @@ static const char * const net_mask_names[] = { + void audit_net_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + + if (address_family_names[sa->u.net->family]) + audit_log_format(ab, " family=\"%s\"", +@@ -78,35 +79,36 @@ void audit_net_cb(struct audit_buffer *ab, void *va) + else + audit_log_format(ab, " family=\"unknown(%d)\"", + sa->u.net->family); +- if (sock_type_names[aad(sa)->net.type]) ++ if (sock_type_names[ad->net.type]) + audit_log_format(ab, " sock_type=\"%s\"", +- sock_type_names[aad(sa)->net.type]); ++ sock_type_names[ad->net.type]); + else + audit_log_format(ab, " sock_type=\"unknown(%d)\"", +- aad(sa)->net.type); +- audit_log_format(ab, " protocol=%d", aad(sa)->net.protocol); ++ ad->net.type); ++ audit_log_format(ab, " protocol=%d", ad->net.protocol); + +- if (aad(sa)->request & NET_PERMS_MASK) { ++ if (ad->request & NET_PERMS_MASK) { + audit_log_format(ab, " requested_mask="); +- aa_audit_perm_mask(ab, aad(sa)->request, NULL, 0, ++ aa_audit_perm_mask(ab, ad->request, NULL, 0, + net_mask_names, NET_PERMS_MASK); + +- if (aad(sa)->denied & NET_PERMS_MASK) { ++ if (ad->denied & NET_PERMS_MASK) { + audit_log_format(ab, " denied_mask="); +- aa_audit_perm_mask(ab, aad(sa)->denied, NULL, 0, ++ aa_audit_perm_mask(ab, ad->denied, NULL, 0, + net_mask_names, NET_PERMS_MASK); + } + } +- if (aad(sa)->peer) { ++ if (ad->peer) { + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, ++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + } + + /* Generic af perm */ +-int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, +- u32 request, u16 family, int type) ++int aa_profile_af_perm(struct aa_profile *profile, ++ struct apparmor_audit_data *ad, u32 request, u16 family, ++ int type) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, + typeof(*rules), list); +@@ -130,17 +132,17 @@ int aa_profile_af_perm(struct aa_profile *profile, struct common_audit_data *sa, + perms = *aa_lookup_perms(&rules->policy, state); + aa_apply_modes_to_perms(profile, &perms); + +- return aa_check_perms(profile, &perms, request, sa, audit_net_cb); ++ return aa_check_perms(profile, &perms, request, ad, audit_net_cb); + } + + int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, + int type, int protocol) + { + struct aa_profile *profile; +- DEFINE_AUDIT_NET(sa, op, NULL, family, type, protocol); ++ DEFINE_AUDIT_NET(ad, op, NULL, family, type, protocol); + + return fn_for_each_confined(label, profile, +- aa_profile_af_perm(profile, &sa, request, family, ++ aa_profile_af_perm(profile, &ad, request, family, + type)); + } + +@@ -155,10 +157,10 @@ static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, + + if (ctx->label != kernel_t && !unconfined(label)) { + struct aa_profile *profile; +- DEFINE_AUDIT_SK(sa, op, sk); ++ DEFINE_AUDIT_SK(ad, op, sk); + + error = fn_for_each_confined(label, profile, +- aa_profile_af_sk_perm(profile, &sa, request, sk)); ++ aa_profile_af_sk_perm(profile, &ad, request, sk)); + } + + return error; +@@ -214,7 +216,7 @@ static int apparmor_secmark_init(struct aa_secmark *secmark) + } + + static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, +- struct common_audit_data *sa) ++ struct apparmor_audit_data *ad) + { + int i, ret; + struct aa_perms perms = { }; +@@ -245,17 +247,17 @@ static int aa_secmark_perm(struct aa_profile *profile, u32 request, u32 secid, + + aa_apply_modes_to_perms(profile, &perms); + +- return aa_check_perms(profile, &perms, request, sa, audit_net_cb); ++ return aa_check_perms(profile, &perms, request, ad, audit_net_cb); + } + + int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, + u32 secid, const struct sock *sk) + { + struct aa_profile *profile; +- DEFINE_AUDIT_SK(sa, op, sk); ++ DEFINE_AUDIT_SK(ad, op, sk); + + return fn_for_each_confined(label, profile, + aa_secmark_perm(profile, request, secid, +- &sa)); ++ &ad)); + } + #endif +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index b9aaaac84d8a2..9a7dbe64f102b 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -723,10 +723,11 @@ static int replacement_allowed(struct aa_profile *profile, int noreplace, + static void audit_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + +- if (aad(sa)->iface.ns) { ++ if (ad->iface.ns) { + audit_log_format(ab, " ns="); +- audit_log_untrustedstring(ab, aad(sa)->iface.ns); ++ audit_log_untrustedstring(ab, ad->iface.ns); + } + } + +@@ -745,15 +746,15 @@ static int audit_policy(struct aa_label *label, const char *op, + const char *ns_name, const char *name, + const char *info, int error) + { +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, op); ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, op); + +- aad(&sa)->iface.ns = ns_name; +- aad(&sa)->name = name; +- aad(&sa)->info = info; +- aad(&sa)->error = error; +- aad(&sa)->label = label; ++ ad.iface.ns = ns_name; ++ ad.name = name; ++ ad.info = info; ++ ad.error = error; ++ ad.label = label; + +- aa_audit_msg(AUDIT_APPARMOR_STATUS, &sa, audit_cb); ++ aa_audit_msg(AUDIT_APPARMOR_STATUS, &ad, audit_cb); + + return error; + } +diff --git a/security/apparmor/policy_unpack.c b/security/apparmor/policy_unpack.c +index b49201306753c..dbc83455d900e 100644 +--- a/security/apparmor/policy_unpack.c ++++ b/security/apparmor/policy_unpack.c +@@ -34,17 +34,18 @@ + static void audit_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + +- if (aad(sa)->iface.ns) { ++ if (ad->iface.ns) { + audit_log_format(ab, " ns="); +- audit_log_untrustedstring(ab, aad(sa)->iface.ns); ++ audit_log_untrustedstring(ab, ad->iface.ns); + } +- if (aad(sa)->name) { ++ if (ad->name) { + audit_log_format(ab, " name="); +- audit_log_untrustedstring(ab, aad(sa)->name); ++ audit_log_untrustedstring(ab, ad->name); + } +- if (aad(sa)->iface.pos) +- audit_log_format(ab, " offset=%ld", aad(sa)->iface.pos); ++ if (ad->iface.pos) ++ audit_log_format(ab, " offset=%ld", ad->iface.pos); + } + + /** +@@ -63,18 +64,18 @@ static int audit_iface(struct aa_profile *new, const char *ns_name, + int error) + { + struct aa_profile *profile = labels_profile(aa_current_raw_label()); +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL); ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_NONE, NULL); + if (e) +- aad(&sa)->iface.pos = e->pos - e->start; +- aad(&sa)->iface.ns = ns_name; ++ ad.iface.pos = e->pos - e->start; ++ ad.iface.ns = ns_name; + if (new) +- aad(&sa)->name = new->base.hname; ++ ad.name = new->base.hname; + else +- aad(&sa)->name = name; +- aad(&sa)->info = info; +- aad(&sa)->error = error; ++ ad.name = name; ++ ad.info = info; ++ ad.error = error; + +- return aa_audit(AUDIT_APPARMOR_STATUS, profile, &sa, audit_cb); ++ return aa_audit(AUDIT_APPARMOR_STATUS, profile, &ad, audit_cb); + } + + void __aa_loaddata_update(struct aa_loaddata *data, long revision) +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index 2bebc5d9e7411..b6b5e1bfe9a26 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -30,12 +30,13 @@ struct aa_sfs_entry aa_sfs_entry_rlimit[] = { + static void audit_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + + audit_log_format(ab, " rlimit=%s value=%lu", +- rlim_names[aad(sa)->rlim.rlim], aad(sa)->rlim.max); +- if (aad(sa)->peer) { ++ rlim_names[ad->rlim.rlim], ad->rlim.max); ++ if (ad->peer) { + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, ++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + } +@@ -49,22 +50,22 @@ static void audit_cb(struct audit_buffer *ab, void *va) + * @info: info being auditing + * @error: error value + * +- * Returns: 0 or sa->error else other error code on failure ++ * Returns: 0 or ad->error else other error code on failure + */ + static int audit_resource(struct aa_profile *profile, unsigned int resource, + unsigned long value, struct aa_label *peer, + const char *info, int error) + { +- DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_RLIMITS, ++ DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_RLIMITS, + OP_SETRLIMIT); + +- aad(&sa)->rlim.rlim = resource; +- aad(&sa)->rlim.max = value; +- aad(&sa)->peer = peer; +- aad(&sa)->info = info; +- aad(&sa)->error = error; ++ ad.rlim.rlim = resource; ++ ad.rlim.max = value; ++ ad.peer = peer; ++ ad.info = info; ++ ad.error = error; + +- return aa_audit(AUDIT_APPARMOR_AUTO, profile, &sa, audit_cb); ++ return aa_audit(AUDIT_APPARMOR_AUTO, profile, &ad, audit_cb); + } + + /** +diff --git a/security/apparmor/task.c b/security/apparmor/task.c +index 84d16a29bfcbc..8bd1f212215c4 100644 +--- a/security/apparmor/task.c ++++ b/security/apparmor/task.c +@@ -208,18 +208,19 @@ static const char *audit_ptrace_mask(u32 mask) + static void audit_ptrace_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; ++ struct apparmor_audit_data *ad = aad(sa); + +- if (aad(sa)->request & AA_PTRACE_PERM_MASK) { ++ if (ad->request & AA_PTRACE_PERM_MASK) { + audit_log_format(ab, " requested_mask=\"%s\"", +- audit_ptrace_mask(aad(sa)->request)); ++ audit_ptrace_mask(ad->request)); + +- if (aad(sa)->denied & AA_PTRACE_PERM_MASK) { ++ if (ad->denied & AA_PTRACE_PERM_MASK) { + audit_log_format(ab, " denied_mask=\"%s\"", +- audit_ptrace_mask(aad(sa)->denied)); ++ audit_ptrace_mask(ad->denied)); + } + } + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(aad(sa)->label), aad(sa)->peer, ++ aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + +@@ -227,51 +228,51 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va) + /* TODO: conditionals */ + static int profile_ptrace_perm(struct aa_profile *profile, + struct aa_label *peer, u32 request, +- struct common_audit_data *sa) ++ struct apparmor_audit_data *ad) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, + typeof(*rules), list); + struct aa_perms perms = { }; + +- aad(sa)->peer = peer; ++ ad->peer = peer; + aa_profile_match_label(profile, rules, peer, AA_CLASS_PTRACE, request, + &perms); + aa_apply_modes_to_perms(profile, &perms); +- return aa_check_perms(profile, &perms, request, sa, audit_ptrace_cb); ++ return aa_check_perms(profile, &perms, request, ad, audit_ptrace_cb); + } + + static int profile_tracee_perm(struct aa_profile *tracee, + struct aa_label *tracer, u32 request, +- struct common_audit_data *sa) ++ struct apparmor_audit_data *ad) + { + if (profile_unconfined(tracee) || unconfined(tracer) || + !ANY_RULE_MEDIATES(&tracee->rules, AA_CLASS_PTRACE)) + return 0; + +- return profile_ptrace_perm(tracee, tracer, request, sa); ++ return profile_ptrace_perm(tracee, tracer, request, ad); + } + + static int profile_tracer_perm(struct aa_profile *tracer, + struct aa_label *tracee, u32 request, +- struct common_audit_data *sa) ++ struct apparmor_audit_data *ad) + { + if (profile_unconfined(tracer)) + return 0; + + if (ANY_RULE_MEDIATES(&tracer->rules, AA_CLASS_PTRACE)) +- return profile_ptrace_perm(tracer, tracee, request, sa); ++ return profile_ptrace_perm(tracer, tracee, request, ad); + + /* profile uses the old style capability check for ptrace */ + if (&tracer->label == tracee) + return 0; + +- aad(sa)->label = &tracer->label; +- aad(sa)->peer = tracee; +- aad(sa)->request = 0; +- aad(sa)->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, ++ ad->label = &tracer->label; ++ ad->peer = tracee; ++ ad->request = 0; ++ ad->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, + CAP_OPT_NONE); + +- return aa_audit(AUDIT_APPARMOR_AUTO, tracer, sa, audit_ptrace_cb); ++ return aa_audit(AUDIT_APPARMOR_AUTO, tracer, ad, audit_ptrace_cb); + } + + /** +-- +2.42.0 + diff --git a/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-audit.c.patch b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-audit.c.patch new file mode 100644 index 00000000000..a082e715916 --- /dev/null +++ b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-audit.c.patch @@ -0,0 +1,37 @@ +From e0d838f05b6f88582e1c6b8dc29c7fcd9ce9499e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Jun 2023 09:13:39 +0800 +Subject: apparmor: Fix kernel-doc warnings in apparmor/audit.c + +From: Gaosheng Cui + +[ Upstream commit 26c9ecb34f5f5fa43c041a220de01d7cbea97dd0 ] + +Fix kernel-doc warnings: + +security/apparmor/audit.c:150: warning: Function parameter or +member 'type' not described in 'aa_audit_msg' + +Signed-off-by: Gaosheng Cui +Signed-off-by: John Johansen +Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation") +Signed-off-by: Sasha Levin +--- + security/apparmor/audit.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c +index 5a7978aa4b19e..a3db0f8bd4f85 100644 +--- a/security/apparmor/audit.c ++++ b/security/apparmor/audit.c +@@ -142,6 +142,7 @@ static void audit_pre(struct audit_buffer *ab, void *ca) + + /** + * aa_audit_msg - Log a message to the audit subsystem ++ * @type: audit type for the message + * @sa: audit event structure (NOT NULL) + * @cb: optional callback fn for type specific fields (MAYBE NULL) + */ +-- +2.42.0 + diff --git a/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-lib.c.patch b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-lib.c.patch new file mode 100644 index 00000000000..c83c7383dd2 --- /dev/null +++ b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-lib.c.patch @@ -0,0 +1,60 @@ +From b6cd9b4ada4e9bde21363488ef32f08e5a3c60d8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Jun 2023 09:13:44 +0800 +Subject: apparmor: Fix kernel-doc warnings in apparmor/lib.c + +From: Gaosheng Cui + +[ Upstream commit 8921482286116af193980f04f2f2755775a410a5 ] + +Fix kernel-doc warnings: + +security/apparmor/lib.c:33: warning: Excess function parameter +'str' description in 'aa_free_str_table' +security/apparmor/lib.c:33: warning: Function parameter or member +'t' not described in 'aa_free_str_table' +security/apparmor/lib.c:94: warning: Function parameter or +member 'n' not described in 'skipn_spaces' +security/apparmor/lib.c:390: warning: Excess function parameter +'deny' description in 'aa_check_perms' + +Signed-off-by: Gaosheng Cui +Signed-off-by: John Johansen +Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation") +Signed-off-by: Sasha Levin +--- + security/apparmor/lib.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c +index a630c951bb3b8..8e1073477c096 100644 +--- a/security/apparmor/lib.c ++++ b/security/apparmor/lib.c +@@ -27,7 +27,7 @@ struct aa_perms allperms = { .allow = ALL_PERMS_MASK, + + /** + * aa_free_str_table - free entries str table +- * @str: the string table to free (MAYBE NULL) ++ * @t: the string table to free (MAYBE NULL) + */ + void aa_free_str_table(struct aa_str_table *t) + { +@@ -85,6 +85,7 @@ char *aa_split_fqname(char *fqname, char **ns_name) + /** + * skipn_spaces - Removes leading whitespace from @str. + * @str: The string to be stripped. ++ * @n: length of str to parse, will stop at \0 if encountered before n + * + * Returns a pointer to the first non-whitespace character in @str. + * if all whitespace will return NULL +@@ -371,7 +372,6 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, + * @profile: profile being checked + * @perms: perms computed for the request + * @request: requested perms +- * @deny: Returns: explicit deny set + * @sa: initialized audit structure (MAY BE NULL if not auditing) + * @cb: callback fn for type specific fields (MAY BE NULL) + * +-- +2.42.0 + diff --git a/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-policy..patch b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-policy..patch new file mode 100644 index 00000000000..b49707629ea --- /dev/null +++ b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-policy..patch @@ -0,0 +1,90 @@ +From 274b48aa36c1e1f1288375fff31d49a9eb40485f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Jun 2023 09:13:49 +0800 +Subject: apparmor: Fix kernel-doc warnings in apparmor/policy.c + +From: Gaosheng Cui + +[ Upstream commit 25ff0ff2d6286928dc516c74b879809c691c2dd8 ] + +Fix kernel-doc warnings: + +security/apparmor/policy.c:294: warning: Function parameter or +member 'proxy' not described in 'aa_alloc_profile' +security/apparmor/policy.c:785: warning: Function parameter or +member 'label' not described in 'aa_policy_view_capable' +security/apparmor/policy.c:785: warning: Function parameter or +member 'ns' not described in 'aa_policy_view_capable' +security/apparmor/policy.c:847: warning: Function parameter or +member 'ns' not described in 'aa_may_manage_policy' +security/apparmor/policy.c:964: warning: Function parameter or +member 'hname' not described in '__lookup_replace' +security/apparmor/policy.c:964: warning: Function parameter or +member 'info' not described in '__lookup_replace' +security/apparmor/policy.c:964: warning: Function parameter or +member 'noreplace' not described in '__lookup_replace' +security/apparmor/policy.c:964: warning: Function parameter or +member 'ns' not described in '__lookup_replace' +security/apparmor/policy.c:964: warning: Function parameter or +member 'p' not described in '__lookup_replace' + +Signed-off-by: Gaosheng Cui +Signed-off-by: John Johansen +Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation") +Signed-off-by: Sasha Levin +--- + security/apparmor/policy.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index ec695a6caac7d..b9aaaac84d8a2 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -286,6 +286,7 @@ void aa_free_profile(struct aa_profile *profile) + /** + * aa_alloc_profile - allocate, initialize and return a new profile + * @hname: name of the profile (NOT NULL) ++ * @proxy: proxy to use OR null if to allocate a new one + * @gfp: allocation type + * + * Returns: refcount profile or NULL on failure +@@ -775,8 +776,9 @@ static int policy_ns_capable(struct aa_label *label, + + /** + * aa_policy_view_capable - check if viewing policy in at @ns is allowed +- * label: label that is trying to view policy in ns +- * ns: namespace being viewed by @label (may be NULL if @label's ns) ++ * @label: label that is trying to view policy in ns ++ * @ns: namespace being viewed by @label (may be NULL if @label's ns) ++ * + * Returns: true if viewing policy is allowed + * + * If @ns is NULL then the namespace being viewed is assumed to be the +@@ -840,6 +842,7 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns) + /** + * aa_may_manage_policy - can the current task manage policy + * @label: label to check if it can manage policy ++ * @ns: namespace being managed by @label (may be NULL if @label's ns) + * @mask: contains the policy manipulation operation being done + * + * Returns: 0 if the task is allowed to manipulate policy else error +@@ -951,11 +954,11 @@ static void __replace_profile(struct aa_profile *old, struct aa_profile *new) + + /** + * __lookup_replace - lookup replacement information for a profile +- * @ns - namespace the lookup occurs in +- * @hname - name of profile to lookup +- * @noreplace - true if not replacing an existing profile +- * @p - Returns: profile to be replaced +- * @info - Returns: info string on why lookup failed ++ * @ns: namespace the lookup occurs in ++ * @hname: name of profile to lookup ++ * @noreplace: true if not replacing an existing profile ++ * @p: Returns - profile to be replaced ++ * @info: Returns - info string on why lookup failed + * + * Returns: profile to replace (no ref) on success else ptr error + */ +-- +2.42.0 + diff --git a/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-resourc.patch b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-resourc.patch new file mode 100644 index 00000000000..44a1bd8e789 --- /dev/null +++ b/queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-resourc.patch @@ -0,0 +1,50 @@ +From 1fa4cbf9881993c63ffe88134a97c923d9434437 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 25 Jun 2023 09:13:46 +0800 +Subject: apparmor: Fix kernel-doc warnings in apparmor/resource.c + +From: Gaosheng Cui + +[ Upstream commit 13c1748e217078d437727eef333cb0387d13bc0e ] + +Fix kernel-doc warnings: + +security/apparmor/resource.c:111: warning: Function parameter or +member 'label' not described in 'aa_task_setrlimit' +security/apparmor/resource.c:111: warning: Function parameter or +member 'new_rlim' not described in 'aa_task_setrlimit' +security/apparmor/resource.c:111: warning: Function parameter or +member 'resource' not described in 'aa_task_setrlimit' +security/apparmor/resource.c:111: warning: Function parameter or +member 'task' not described in 'aa_task_setrlimit' + +Signed-off-by: Gaosheng Cui +Signed-off-by: John Johansen +Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation") +Signed-off-by: Sasha Levin +--- + security/apparmor/resource.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index e859481648962..2bebc5d9e7411 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -97,10 +97,10 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource, + + /** + * aa_task_setrlimit - test permission to set an rlimit +- * @label - label confining the task (NOT NULL) +- * @task - task the resource is being set on +- * @resource - the resource being set +- * @new_rlim - the new resource limit (NOT NULL) ++ * @label: label confining the task (NOT NULL) ++ * @task: task the resource is being set on ++ * @resource: the resource being set ++ * @new_rlim: the new resource limit (NOT NULL) + * + * Control raising the processes hard limit. + * +-- +2.42.0 + diff --git a/queue-6.6/apparmor-fix-regression-in-mount-mediation.patch b/queue-6.6/apparmor-fix-regression-in-mount-mediation.patch new file mode 100644 index 00000000000..7f8a8b0ade6 --- /dev/null +++ b/queue-6.6/apparmor-fix-regression-in-mount-mediation.patch @@ -0,0 +1,165 @@ +From 9da47efe8ca49d251e3bd334c61d6bcdb215c51a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 10 Sep 2023 03:35:22 -0700 +Subject: apparmor: Fix regression in mount mediation + +From: John Johansen + +[ Upstream commit 157a3537d6bc28ceb9a11fc8cb67f2152d860146 ] + +commit 2db154b3ea8e ("vfs: syscall: Add move_mount(2) to move mounts around") + +introduced a new move_mount(2) system call and a corresponding new LSM +security_move_mount hook but did not implement this hook for any +existing LSM. This creates a regression for AppArmor mediation of +mount. This patch provides a base mapping of the move_mount syscall to +the existing mount mediation. In the future we may introduce +additional mediations around the new mount calls. + +Fixes: 2db154b3ea8e ("vfs: syscall: Add move_mount(2) to move mounts around") +CC: stable@vger.kernel.org +Reported-by: Andreas Steinmetz +Signed-off-by: John Johansen +Signed-off-by: Sasha Levin +--- + security/apparmor/include/mount.h | 7 +++-- + security/apparmor/lsm.c | 20 ++++++++++++-- + security/apparmor/mount.c | 46 +++++++++++++++++++------------ + 3 files changed, 51 insertions(+), 22 deletions(-) + +diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h +index 10c76f906a653..46834f8281794 100644 +--- a/security/apparmor/include/mount.h ++++ b/security/apparmor/include/mount.h +@@ -38,9 +38,12 @@ int aa_mount_change_type(const struct cred *subj_cred, + struct aa_label *label, const struct path *path, + unsigned long flags); + ++int aa_move_mount_old(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, ++ const char *old_name); + int aa_move_mount(const struct cred *subj_cred, +- struct aa_label *label, const struct path *path, +- const char *old_name); ++ struct aa_label *label, const struct path *from_path, ++ const struct path *to_path); + + int aa_new_mount(const struct cred *subj_cred, + struct aa_label *label, const char *dev_name, +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 60f95cc4532a8..6fdab1b5ede5c 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -607,8 +607,8 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path, + error = aa_mount_change_type(current_cred(), label, + path, flags); + else if (flags & MS_MOVE) +- error = aa_move_mount(current_cred(), label, path, +- dev_name); ++ error = aa_move_mount_old(current_cred(), label, path, ++ dev_name); + else + error = aa_new_mount(current_cred(), label, dev_name, + path, type, flags, data); +@@ -618,6 +618,21 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path, + return error; + } + ++static int apparmor_move_mount(const struct path *from_path, ++ const struct path *to_path) ++{ ++ struct aa_label *label; ++ int error = 0; ++ ++ label = __begin_current_label_crit_section(); ++ if (!unconfined(label)) ++ error = aa_move_mount(current_cred(), label, from_path, ++ to_path); ++ __end_current_label_crit_section(label); ++ ++ return error; ++} ++ + static int apparmor_sb_umount(struct vfsmount *mnt, int flags) + { + struct aa_label *label; +@@ -1240,6 +1255,7 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = { + LSM_HOOK_INIT(capget, apparmor_capget), + LSM_HOOK_INIT(capable, apparmor_capable), + ++ LSM_HOOK_INIT(move_mount, apparmor_move_mount), + LSM_HOOK_INIT(sb_mount, apparmor_sb_mount), + LSM_HOOK_INIT(sb_umount, apparmor_sb_umount), + LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot), +diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c +index 2bb77aacc49ae..f2a114e540079 100644 +--- a/security/apparmor/mount.c ++++ b/security/apparmor/mount.c +@@ -483,36 +483,46 @@ int aa_mount_change_type(const struct cred *subj_cred, + } + + int aa_move_mount(const struct cred *subj_cred, +- struct aa_label *label, const struct path *path, +- const char *orig_name) ++ struct aa_label *label, const struct path *from_path, ++ const struct path *to_path) + { + struct aa_profile *profile; +- char *buffer = NULL, *old_buffer = NULL; +- struct path old_path; ++ char *to_buffer = NULL, *from_buffer = NULL; + int error; + + AA_BUG(!label); +- AA_BUG(!path); ++ AA_BUG(!from_path); ++ AA_BUG(!to_path); ++ ++ to_buffer = aa_get_buffer(false); ++ from_buffer = aa_get_buffer(false); ++ error = -ENOMEM; ++ if (!to_buffer || !from_buffer) ++ goto out; ++ error = fn_for_each_confined(label, profile, ++ match_mnt(subj_cred, profile, to_path, to_buffer, ++ from_path, from_buffer, ++ NULL, MS_MOVE, NULL, false)); ++out: ++ aa_put_buffer(to_buffer); ++ aa_put_buffer(from_buffer); ++ ++ return error; ++} ++ ++int aa_move_mount_old(const struct cred *subj_cred, struct aa_label *label, ++ const struct path *path, const char *orig_name) ++{ ++ struct path old_path; ++ int error; + + if (!orig_name || !*orig_name) + return -EINVAL; +- + error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path); + if (error) + return error; + +- buffer = aa_get_buffer(false); +- old_buffer = aa_get_buffer(false); +- error = -ENOMEM; +- if (!buffer || !old_buffer) +- goto out; +- error = fn_for_each_confined(label, profile, +- match_mnt(subj_cred, profile, path, buffer, &old_path, +- old_buffer, +- NULL, MS_MOVE, NULL, false)); +-out: +- aa_put_buffer(buffer); +- aa_put_buffer(old_buffer); ++ error = aa_move_mount(subj_cred, label, &old_path, path); + path_put(&old_path); + + return error; +-- +2.42.0 + diff --git a/queue-6.6/apparmor-pass-cred-through-to-audit-info.patch b/queue-6.6/apparmor-pass-cred-through-to-audit-info.patch new file mode 100644 index 00000000000..9ac7f206f91 --- /dev/null +++ b/queue-6.6/apparmor-pass-cred-through-to-audit-info.patch @@ -0,0 +1,1933 @@ +From 6868e7132f91ab9266f4c4f2ae645a42a5a089cc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Sep 2022 20:48:48 -0700 +Subject: apparmor: pass cred through to audit info. + +From: John Johansen + +[ Upstream commit 90c436a64a6e20482a9a613c47eb4af2e8a5328e ] + +The cred is needed to properly audit some messages, and will be needed +in the future for uid conditional mediation. So pass it through to +where the apparmor_audit_data struct gets defined. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation") +Signed-off-by: Sasha Levin +--- + security/apparmor/apparmorfs.c | 11 ++- + security/apparmor/capability.c | 5 +- + security/apparmor/domain.c | 97 +++++++++++------- + security/apparmor/file.c | 131 +++++++++++++++++-------- + security/apparmor/include/audit.h | 1 + + security/apparmor/include/capability.h | 3 +- + security/apparmor/include/file.h | 17 ++-- + security/apparmor/include/ipc.h | 4 +- + security/apparmor/include/mount.h | 21 ++-- + security/apparmor/include/net.h | 6 +- + security/apparmor/include/policy.h | 9 +- + security/apparmor/include/resource.h | 3 +- + security/apparmor/include/task.h | 3 +- + security/apparmor/ipc.c | 14 ++- + security/apparmor/lsm.c | 85 +++++++++------- + security/apparmor/mount.c | 85 ++++++++++------ + security/apparmor/net.c | 17 ++-- + security/apparmor/policy.c | 33 ++++--- + security/apparmor/resource.c | 23 +++-- + security/apparmor/task.c | 31 +++--- + 20 files changed, 388 insertions(+), 211 deletions(-) + +diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c +index bd6a910f65282..261cef4c622fb 100644 +--- a/security/apparmor/apparmorfs.c ++++ b/security/apparmor/apparmorfs.c +@@ -423,7 +423,7 @@ static ssize_t policy_update(u32 mask, const char __user *buf, size_t size, + /* high level check about policy management - fine grained in + * below after unpack + */ +- error = aa_may_manage_policy(label, ns, mask); ++ error = aa_may_manage_policy(current_cred(), label, ns, mask); + if (error) + goto end_section; + +@@ -486,7 +486,8 @@ static ssize_t profile_remove(struct file *f, const char __user *buf, + /* high level check about policy management - fine grained in + * below after unpack + */ +- error = aa_may_manage_policy(label, ns, AA_MAY_REMOVE_POLICY); ++ error = aa_may_manage_policy(current_cred(), label, ns, ++ AA_MAY_REMOVE_POLICY); + if (error) + goto out; + +@@ -1805,7 +1806,8 @@ static int ns_mkdir_op(struct mnt_idmap *idmap, struct inode *dir, + int error; + + label = begin_current_label_crit_section(); +- error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY); ++ error = aa_may_manage_policy(current_cred(), label, NULL, ++ AA_MAY_LOAD_POLICY); + end_current_label_crit_section(label); + if (error) + return error; +@@ -1854,7 +1856,8 @@ static int ns_rmdir_op(struct inode *dir, struct dentry *dentry) + int error; + + label = begin_current_label_crit_section(); +- error = aa_may_manage_policy(label, NULL, AA_MAY_LOAD_POLICY); ++ error = aa_may_manage_policy(current_cred(), label, NULL, ++ AA_MAY_LOAD_POLICY); + end_current_label_crit_section(label); + if (error) + return error; +diff --git a/security/apparmor/capability.c b/security/apparmor/capability.c +index 58490cca035da..2fb6a2ea0b998 100644 +--- a/security/apparmor/capability.c ++++ b/security/apparmor/capability.c +@@ -140,6 +140,7 @@ static int profile_capable(struct aa_profile *profile, int cap, + + /** + * aa_capable - test permission to use capability ++ * @subj_cread: cred we are testing capability against + * @label: label being tested for capability (NOT NULL) + * @cap: capability to be tested + * @opts: CAP_OPT_NOAUDIT bit determines whether audit record is generated +@@ -148,12 +149,14 @@ static int profile_capable(struct aa_profile *profile, int cap, + * + * Returns: 0 on success, or else an error code. + */ +-int aa_capable(struct aa_label *label, int cap, unsigned int opts) ++int aa_capable(const struct cred *subj_cred, struct aa_label *label, ++ int cap, unsigned int opts) + { + struct aa_profile *profile; + int error = 0; + DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_CAP, AA_CLASS_CAP, OP_CAPABLE); + ++ ad.subj_cred = subj_cred; + ad.common.u.cap = cap; + error = fn_for_each_confined(label, profile, + profile_capable(profile, cap, opts, &ad)); +diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c +index f3715cda59c52..543105cf7e334 100644 +--- a/security/apparmor/domain.c ++++ b/security/apparmor/domain.c +@@ -31,6 +31,7 @@ + + /** + * may_change_ptraced_domain - check if can change profile on ptraced task ++ * @cred: cred of task changing domain + * @to_label: profile to change to (NOT NULL) + * @info: message if there is an error + * +@@ -39,28 +40,34 @@ + * + * Returns: %0 or error if change not allowed + */ +-static int may_change_ptraced_domain(struct aa_label *to_label, ++static int may_change_ptraced_domain(const struct cred *to_cred, ++ struct aa_label *to_label, + const char **info) + { + struct task_struct *tracer; + struct aa_label *tracerl = NULL; ++ const struct cred *tracer_cred = NULL; ++ + int error = 0; + + rcu_read_lock(); + tracer = ptrace_parent(current); +- if (tracer) ++ if (tracer) { + /* released below */ + tracerl = aa_get_task_label(tracer); +- ++ tracer_cred = get_task_cred(tracer); ++ } + /* not ptraced */ + if (!tracer || unconfined(tracerl)) + goto out; + +- error = aa_may_ptrace(tracerl, to_label, PTRACE_MODE_ATTACH); ++ error = aa_may_ptrace(tracer_cred, tracerl, to_cred, to_label, ++ PTRACE_MODE_ATTACH); + + out: + rcu_read_unlock(); + aa_put_label(tracerl); ++ put_cred(tracer_cred); + + if (error) + *info = "ptrace prevents transition"; +@@ -619,7 +626,8 @@ static struct aa_label *x_to_label(struct aa_profile *profile, + return new; + } + +-static struct aa_label *profile_transition(struct aa_profile *profile, ++static struct aa_label *profile_transition(const struct cred *subj_cred, ++ struct aa_profile *profile, + const struct linux_binprm *bprm, + char *buffer, struct path_cond *cond, + bool *secure_exec) +@@ -709,7 +717,8 @@ static struct aa_label *profile_transition(struct aa_profile *profile, + } + + audit: +- aa_audit_file(profile, &perms, OP_EXEC, MAY_EXEC, name, target, new, ++ aa_audit_file(subj_cred, profile, &perms, OP_EXEC, MAY_EXEC, name, ++ target, new, + cond->uid, info, error); + if (!new || nonewprivs) { + aa_put_label(new); +@@ -719,7 +728,8 @@ static struct aa_label *profile_transition(struct aa_profile *profile, + return new; + } + +-static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec, ++static int profile_onexec(const struct cred *subj_cred, ++ struct aa_profile *profile, struct aa_label *onexec, + bool stack, const struct linux_binprm *bprm, + char *buffer, struct path_cond *cond, + bool *secure_exec) +@@ -787,13 +797,15 @@ static int profile_onexec(struct aa_profile *profile, struct aa_label *onexec, + } + + audit: +- return aa_audit_file(profile, &perms, OP_EXEC, AA_MAY_ONEXEC, xname, ++ return aa_audit_file(subj_cred, profile, &perms, OP_EXEC, ++ AA_MAY_ONEXEC, xname, + NULL, onexec, cond->uid, info, error); + } + + /* ensure none ns domain transitions are correctly applied with onexec */ + +-static struct aa_label *handle_onexec(struct aa_label *label, ++static struct aa_label *handle_onexec(const struct cred *subj_cred, ++ struct aa_label *label, + struct aa_label *onexec, bool stack, + const struct linux_binprm *bprm, + char *buffer, struct path_cond *cond, +@@ -810,26 +822,28 @@ static struct aa_label *handle_onexec(struct aa_label *label, + + if (!stack) { + error = fn_for_each_in_ns(label, profile, +- profile_onexec(profile, onexec, stack, ++ profile_onexec(subj_cred, profile, onexec, stack, + bprm, buffer, cond, unsafe)); + if (error) + return ERR_PTR(error); + new = fn_label_build_in_ns(label, profile, GFP_KERNEL, + aa_get_newest_label(onexec), +- profile_transition(profile, bprm, buffer, ++ profile_transition(subj_cred, profile, bprm, ++ buffer, + cond, unsafe)); + + } else { + /* TODO: determine how much we want to loosen this */ + error = fn_for_each_in_ns(label, profile, +- profile_onexec(profile, onexec, stack, bprm, ++ profile_onexec(subj_cred, profile, onexec, stack, bprm, + buffer, cond, unsafe)); + if (error) + return ERR_PTR(error); + new = fn_label_build_in_ns(label, profile, GFP_KERNEL, + aa_label_merge(&profile->label, onexec, + GFP_KERNEL), +- profile_transition(profile, bprm, buffer, ++ profile_transition(subj_cred, profile, bprm, ++ buffer, + cond, unsafe)); + } + +@@ -838,7 +852,8 @@ static struct aa_label *handle_onexec(struct aa_label *label, + + /* TODO: get rid of GLOBAL_ROOT_UID */ + error = fn_for_each_in_ns(label, profile, +- aa_audit_file(profile, &nullperms, OP_CHANGE_ONEXEC, ++ aa_audit_file(subj_cred, profile, &nullperms, ++ OP_CHANGE_ONEXEC, + AA_MAY_ONEXEC, bprm->filename, NULL, + onexec, GLOBAL_ROOT_UID, + "failed to build target label", -ENOMEM)); +@@ -857,6 +872,7 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) + { + struct aa_task_ctx *ctx; + struct aa_label *label, *new = NULL; ++ const struct cred *subj_cred; + struct aa_profile *profile; + char *buffer = NULL; + const char *info = NULL; +@@ -869,6 +885,7 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) + file_inode(bprm->file)->i_mode + }; + ++ subj_cred = current_cred(); + ctx = task_ctx(current); + AA_BUG(!cred_label(bprm->cred)); + AA_BUG(!ctx); +@@ -895,11 +912,12 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) + + /* Test for onexec first as onexec override other x transitions. */ + if (ctx->onexec) +- new = handle_onexec(label, ctx->onexec, ctx->token, ++ new = handle_onexec(subj_cred, label, ctx->onexec, ctx->token, + bprm, buffer, &cond, &unsafe); + else + new = fn_label_build(label, profile, GFP_KERNEL, +- profile_transition(profile, bprm, buffer, ++ profile_transition(subj_cred, profile, bprm, ++ buffer, + &cond, &unsafe)); + + AA_BUG(!new); +@@ -934,7 +952,7 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) + + if (bprm->unsafe & (LSM_UNSAFE_PTRACE)) { + /* TODO: test needs to be profile of label to new */ +- error = may_change_ptraced_domain(new, &info); ++ error = may_change_ptraced_domain(bprm->cred, new, &info); + if (error) + goto audit; + } +@@ -971,7 +989,8 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) + + audit: + error = fn_for_each(label, profile, +- aa_audit_file(profile, &nullperms, OP_EXEC, MAY_EXEC, ++ aa_audit_file(current_cred(), profile, &nullperms, ++ OP_EXEC, MAY_EXEC, + bprm->filename, NULL, new, + vfsuid_into_kuid(vfsuid), info, error)); + aa_put_label(new); +@@ -987,7 +1006,8 @@ int apparmor_bprm_creds_for_exec(struct linux_binprm *bprm) + * + * Returns: label for hat transition OR ERR_PTR. Does NOT return NULL + */ +-static struct aa_label *build_change_hat(struct aa_profile *profile, ++static struct aa_label *build_change_hat(const struct cred *subj_cred, ++ struct aa_profile *profile, + const char *name, bool sibling) + { + struct aa_profile *root, *hat = NULL; +@@ -1019,7 +1039,8 @@ static struct aa_label *build_change_hat(struct aa_profile *profile, + aa_put_profile(root); + + audit: +- aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, AA_MAY_CHANGEHAT, ++ aa_audit_file(subj_cred, profile, &nullperms, OP_CHANGE_HAT, ++ AA_MAY_CHANGEHAT, + name, hat ? hat->base.hname : NULL, + hat ? &hat->label : NULL, GLOBAL_ROOT_UID, info, + error); +@@ -1035,7 +1056,8 @@ static struct aa_label *build_change_hat(struct aa_profile *profile, + * + * Returns: label for hat transition or ERR_PTR. Does not return NULL + */ +-static struct aa_label *change_hat(struct aa_label *label, const char *hats[], ++static struct aa_label *change_hat(const struct cred *subj_cred, ++ struct aa_label *label, const char *hats[], + int count, int flags) + { + struct aa_profile *profile, *root, *hat = NULL; +@@ -1111,7 +1133,8 @@ static struct aa_label *change_hat(struct aa_label *label, const char *hats[], + */ + /* TODO: get rid of GLOBAL_ROOT_UID */ + if (count > 1 || COMPLAIN_MODE(profile)) { +- aa_audit_file(profile, &nullperms, OP_CHANGE_HAT, ++ aa_audit_file(subj_cred, profile, &nullperms, ++ OP_CHANGE_HAT, + AA_MAY_CHANGEHAT, name, NULL, NULL, + GLOBAL_ROOT_UID, info, error); + } +@@ -1120,7 +1143,8 @@ static struct aa_label *change_hat(struct aa_label *label, const char *hats[], + + build: + new = fn_label_build_in_ns(label, profile, GFP_KERNEL, +- build_change_hat(profile, name, sibling), ++ build_change_hat(subj_cred, profile, name, ++ sibling), + aa_get_label(&profile->label)); + if (!new) { + info = "label build failed"; +@@ -1150,7 +1174,7 @@ static struct aa_label *change_hat(struct aa_label *label, const char *hats[], + */ + int aa_change_hat(const char *hats[], int count, u64 token, int flags) + { +- const struct cred *cred; ++ const struct cred *subj_cred; + struct aa_task_ctx *ctx = task_ctx(current); + struct aa_label *label, *previous, *new = NULL, *target = NULL; + struct aa_profile *profile; +@@ -1159,8 +1183,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) + int error = 0; + + /* released below */ +- cred = get_current_cred(); +- label = aa_get_newest_cred_label(cred); ++ subj_cred = get_current_cred(); ++ label = aa_get_newest_cred_label(subj_cred); + previous = aa_get_newest_label(ctx->previous); + + /* +@@ -1180,7 +1204,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) + } + + if (count) { +- new = change_hat(label, hats, count, flags); ++ new = change_hat(subj_cred, label, hats, count, flags); + AA_BUG(!new); + if (IS_ERR(new)) { + error = PTR_ERR(new); +@@ -1189,7 +1213,8 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) + goto out; + } + +- error = may_change_ptraced_domain(new, &info); ++ /* target cred is the same as current except new label */ ++ error = may_change_ptraced_domain(subj_cred, new, &info); + if (error) + goto fail; + +@@ -1242,7 +1267,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) + aa_put_label(new); + aa_put_label(previous); + aa_put_label(label); +- put_cred(cred); ++ put_cred(subj_cred); + + return error; + +@@ -1252,7 +1277,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) + + fail: + fn_for_each_in_ns(label, profile, +- aa_audit_file(profile, &perms, OP_CHANGE_HAT, ++ aa_audit_file(subj_cred, profile, &perms, OP_CHANGE_HAT, + AA_MAY_CHANGEHAT, NULL, NULL, target, + GLOBAL_ROOT_UID, info, error)); + +@@ -1261,6 +1286,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, int flags) + + + static int change_profile_perms_wrapper(const char *op, const char *name, ++ const struct cred *subj_cred, + struct aa_profile *profile, + struct aa_label *target, bool stack, + u32 request, struct aa_perms *perms) +@@ -1275,7 +1301,8 @@ static int change_profile_perms_wrapper(const char *op, const char *name, + rules->file.start[AA_CLASS_FILE], + perms); + if (error) +- error = aa_audit_file(profile, perms, op, request, name, ++ error = aa_audit_file(subj_cred, profile, perms, op, request, ++ name, + NULL, target, GLOBAL_ROOT_UID, info, + error); + +@@ -1304,6 +1331,7 @@ int aa_change_profile(const char *fqname, int flags) + const char *auditname = fqname; /* retain leading & if stack */ + bool stack = flags & AA_CHANGE_STACK; + struct aa_task_ctx *ctx = task_ctx(current); ++ const struct cred *subj_cred = get_current_cred(); + int error = 0; + char *op; + u32 request; +@@ -1381,6 +1409,7 @@ int aa_change_profile(const char *fqname, int flags) + */ + error = fn_for_each_in_ns(label, profile, + change_profile_perms_wrapper(op, auditname, ++ subj_cred, + profile, target, stack, + request, &perms)); + if (error) +@@ -1391,7 +1420,7 @@ int aa_change_profile(const char *fqname, int flags) + + check: + /* check if tracing task is allowed to trace target domain */ +- error = may_change_ptraced_domain(target, &info); ++ error = may_change_ptraced_domain(subj_cred, target, &info); + if (error && !fn_for_each_in_ns(label, profile, + COMPLAIN_MODE(profile))) + goto audit; +@@ -1451,7 +1480,8 @@ int aa_change_profile(const char *fqname, int flags) + + audit: + error = fn_for_each_in_ns(label, profile, +- aa_audit_file(profile, &perms, op, request, auditname, ++ aa_audit_file(subj_cred, ++ profile, &perms, op, request, auditname, + NULL, new ? new : target, + GLOBAL_ROOT_UID, info, error)); + +@@ -1459,6 +1489,7 @@ int aa_change_profile(const char *fqname, int flags) + aa_put_label(new); + aa_put_label(target); + aa_put_label(label); ++ put_cred(subj_cred); + + return error; + } +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index 5bfa70a972071..6fd21324a097f 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -45,7 +45,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) + { + struct common_audit_data *sa = va; + struct apparmor_audit_data *ad = aad(sa); +- kuid_t fsuid = current_fsuid(); ++ kuid_t fsuid = ad->subj_cred ? ad->subj_cred->fsuid : current_fsuid(); + char str[10]; + + if (ad->request & AA_AUDIT_FILE_MASK) { +@@ -77,6 +77,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) + + /** + * aa_audit_file - handle the auditing of file operations ++ * @subj_cred: cred of the subject + * @profile: the profile being enforced (NOT NULL) + * @perms: the permissions computed for the request (NOT NULL) + * @op: operation being mediated +@@ -90,7 +91,8 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) + * + * Returns: %0 or error on failure + */ +-int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms, ++int aa_audit_file(const struct cred *subj_cred, ++ struct aa_profile *profile, struct aa_perms *perms, + const char *op, u32 request, const char *name, + const char *target, struct aa_label *tlabel, + kuid_t ouid, const char *info, int error) +@@ -98,6 +100,7 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms, + int type = AUDIT_APPARMOR_AUTO; + DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_TASK, AA_CLASS_FILE, op); + ++ ad.subj_cred = subj_cred; + ad.request = request; + ad.name = name; + ad.fs.target = target; +@@ -141,7 +144,21 @@ int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms, + return aa_audit(type, profile, &ad, file_audit_cb); + } + +-static int path_name(const char *op, struct aa_label *label, ++/** ++ * is_deleted - test if a file has been completely unlinked ++ * @dentry: dentry of file to test for deletion (NOT NULL) ++ * ++ * 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 true; ++ return false; ++} ++ ++static int path_name(const char *op, const struct cred *subj_cred, ++ struct aa_label *label, + const struct path *path, int flags, char *buffer, + const char **name, struct path_cond *cond, u32 request) + { +@@ -153,7 +170,8 @@ static int path_name(const char *op, struct aa_label *label, + labels_profile(label)->disconnected); + if (error) { + fn_for_each_confined(label, profile, +- aa_audit_file(profile, &nullperms, op, request, *name, ++ aa_audit_file(subj_cred, ++ profile, &nullperms, op, request, *name, + NULL, NULL, cond->uid, info, error)); + return error; + } +@@ -207,9 +225,9 @@ aa_state_t aa_str_perms(struct aa_policydb *file_rules, aa_state_t start, + return state; + } + +-static int __aa_path_perm(const char *op, struct aa_profile *profile, +- const char *name, u32 request, +- struct path_cond *cond, int flags, ++static int __aa_path_perm(const char *op, const struct cred *subj_cred, ++ struct aa_profile *profile, const char *name, ++ u32 request, struct path_cond *cond, int flags, + struct aa_perms *perms) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, +@@ -222,12 +240,14 @@ static int __aa_path_perm(const char *op, struct aa_profile *profile, + name, cond, perms); + if (request & ~perms->allow) + e = -EACCES; +- return aa_audit_file(profile, perms, op, request, name, NULL, NULL, ++ return aa_audit_file(subj_cred, ++ profile, perms, op, request, name, NULL, NULL, + cond->uid, NULL, e); + } + + +-static int profile_path_perm(const char *op, struct aa_profile *profile, ++static int profile_path_perm(const char *op, const struct cred *subj_cred, ++ struct aa_profile *profile, + const struct path *path, char *buffer, u32 request, + struct path_cond *cond, int flags, + struct aa_perms *perms) +@@ -238,18 +258,19 @@ static int profile_path_perm(const char *op, struct aa_profile *profile, + if (profile_unconfined(profile)) + return 0; + +- error = path_name(op, &profile->label, path, ++ error = path_name(op, subj_cred, &profile->label, path, + flags | profile->path_flags, buffer, &name, cond, + request); + if (error) + return error; +- return __aa_path_perm(op, profile, name, request, cond, flags, +- perms); ++ return __aa_path_perm(op, subj_cred, profile, name, request, cond, ++ flags, perms); + } + + /** + * aa_path_perm - do permissions check & audit for @path + * @op: operation being checked ++ * @subj_cred: subject cred + * @label: profile being enforced (NOT NULL) + * @path: path to check permissions of (NOT NULL) + * @flags: any additional path flags beyond what the profile specifies +@@ -258,7 +279,8 @@ static int profile_path_perm(const char *op, struct aa_profile *profile, + * + * Returns: %0 else error if access denied or other error + */ +-int aa_path_perm(const char *op, struct aa_label *label, ++int aa_path_perm(const char *op, const struct cred *subj_cred, ++ struct aa_label *label, + const struct path *path, int flags, u32 request, + struct path_cond *cond) + { +@@ -273,8 +295,8 @@ int aa_path_perm(const char *op, struct aa_label *label, + if (!buffer) + return -ENOMEM; + error = fn_for_each_confined(label, profile, +- profile_path_perm(op, profile, path, buffer, request, +- cond, flags, &perms)); ++ profile_path_perm(op, subj_cred, profile, path, buffer, ++ request, cond, flags, &perms)); + + aa_put_buffer(buffer); + +@@ -301,7 +323,8 @@ static inline bool xindex_is_subset(u32 link, u32 target) + return true; + } + +-static int profile_path_link(struct aa_profile *profile, ++static int profile_path_link(const struct cred *subj_cred, ++ struct aa_profile *profile, + const struct path *link, char *buffer, + const struct path *target, char *buffer2, + struct path_cond *cond) +@@ -315,13 +338,15 @@ static int profile_path_link(struct aa_profile *profile, + aa_state_t state; + int error; + +- error = path_name(OP_LINK, &profile->label, link, profile->path_flags, ++ error = path_name(OP_LINK, subj_cred, &profile->label, link, ++ profile->path_flags, + buffer, &lname, cond, AA_MAY_LINK); + if (error) + goto audit; + + /* buffer2 freed below, tname is pointer in buffer2 */ +- error = path_name(OP_LINK, &profile->label, target, profile->path_flags, ++ error = path_name(OP_LINK, subj_cred, &profile->label, target, ++ profile->path_flags, + buffer2, &tname, cond, AA_MAY_LINK); + if (error) + goto audit; +@@ -381,12 +406,14 @@ static int profile_path_link(struct aa_profile *profile, + error = 0; + + audit: +- return aa_audit_file(profile, &lperms, OP_LINK, request, lname, tname, ++ return aa_audit_file(subj_cred, ++ profile, &lperms, OP_LINK, request, lname, tname, + NULL, cond->uid, info, error); + } + + /** + * aa_path_link - Handle hard link permission check ++ * @subj_cred: subject cred + * @label: the label being enforced (NOT NULL) + * @old_dentry: the target dentry (NOT NULL) + * @new_dir: directory the new link will be created in (NOT NULL) +@@ -403,7 +430,8 @@ static int profile_path_link(struct aa_profile *profile, + * + * Returns: %0 if allowed else error + */ +-int aa_path_link(struct aa_label *label, struct dentry *old_dentry, ++int aa_path_link(const struct cred *subj_cred, ++ struct aa_label *label, struct dentry *old_dentry, + const struct path *new_dir, struct dentry *new_dentry) + { + struct path link = { .mnt = new_dir->mnt, .dentry = new_dentry }; +@@ -424,8 +452,8 @@ int aa_path_link(struct aa_label *label, struct dentry *old_dentry, + goto out; + + error = fn_for_each_confined(label, profile, +- profile_path_link(profile, &link, buffer, &target, +- buffer2, &cond)); ++ profile_path_link(subj_cred, profile, &link, buffer, ++ &target, buffer2, &cond)); + out: + aa_put_buffer(buffer); + aa_put_buffer(buffer2); +@@ -453,7 +481,8 @@ static void update_file_ctx(struct aa_file_ctx *fctx, struct aa_label *label, + spin_unlock(&fctx->lock); + } + +-static int __file_path_perm(const char *op, struct aa_label *label, ++static int __file_path_perm(const char *op, const struct cred *subj_cred, ++ struct aa_label *label, + struct aa_label *flabel, struct file *file, + u32 request, u32 denied, bool in_atomic) + { +@@ -480,7 +509,8 @@ static int __file_path_perm(const char *op, struct aa_label *label, + + /* check every profile in task label not in current cache */ + error = fn_for_each_not_in_set(flabel, label, profile, +- profile_path_perm(op, profile, &file->f_path, buffer, ++ profile_path_perm(op, subj_cred, profile, ++ &file->f_path, buffer, + request, &cond, flags, &perms)); + if (denied && !error) { + /* +@@ -493,12 +523,14 @@ static int __file_path_perm(const char *op, struct aa_label *label, + */ + if (label == flabel) + error = fn_for_each(label, profile, +- profile_path_perm(op, profile, &file->f_path, ++ profile_path_perm(op, subj_cred, ++ profile, &file->f_path, + buffer, request, &cond, flags, + &perms)); + else + error = fn_for_each_not_in_set(label, flabel, profile, +- profile_path_perm(op, profile, &file->f_path, ++ profile_path_perm(op, subj_cred, ++ profile, &file->f_path, + buffer, request, &cond, flags, + &perms)); + } +@@ -510,7 +542,8 @@ static int __file_path_perm(const char *op, struct aa_label *label, + return error; + } + +-static int __file_sock_perm(const char *op, struct aa_label *label, ++static int __file_sock_perm(const char *op, const struct cred *subj_cred, ++ struct aa_label *label, + struct aa_label *flabel, struct file *file, + u32 request, u32 denied) + { +@@ -524,11 +557,12 @@ static int __file_sock_perm(const char *op, struct aa_label *label, + return 0; + + /* TODO: improve to skip profiles cached in flabel */ +- error = aa_sock_file_perm(label, op, request, sock); ++ error = aa_sock_file_perm(subj_cred, label, op, request, sock); + if (denied) { + /* TODO: improve to skip profiles checked above */ + /* check every profile in file label to is cached */ +- last_error(error, aa_sock_file_perm(flabel, op, request, sock)); ++ last_error(error, aa_sock_file_perm(subj_cred, flabel, op, ++ request, sock)); + } + if (!error) + update_file_ctx(file_ctx(file), label, request); +@@ -539,6 +573,7 @@ static int __file_sock_perm(const char *op, struct aa_label *label, + /** + * aa_file_perm - do permission revalidation check & audit for @file + * @op: operation being checked ++ * @subj_cred: subject cred + * @label: label being enforced (NOT NULL) + * @file: file to revalidate access permissions on (NOT NULL) + * @request: requested permissions +@@ -546,7 +581,8 @@ static int __file_sock_perm(const char *op, struct aa_label *label, + * + * Returns: %0 if access allowed else error + */ +-int aa_file_perm(const char *op, struct aa_label *label, struct file *file, ++int aa_file_perm(const char *op, const struct cred *subj_cred, ++ struct aa_label *label, struct file *file, + u32 request, bool in_atomic) + { + struct aa_file_ctx *fctx; +@@ -582,19 +618,19 @@ int aa_file_perm(const char *op, struct aa_label *label, struct file *file, + /* 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, in_atomic); ++ error = __file_path_perm(op, subj_cred, label, flabel, file, ++ request, denied, in_atomic); + + else if (S_ISSOCK(file_inode(file)->i_mode)) +- error = __file_sock_perm(op, label, flabel, file, request, +- denied); ++ error = __file_sock_perm(op, subj_cred, label, flabel, file, ++ request, denied); + aa_put_label(flabel); + + done: + return error; + } + +-static void revalidate_tty(struct aa_label *label) ++static void revalidate_tty(const struct cred *subj_cred, struct aa_label *label) + { + struct tty_struct *tty; + int drop_tty = 0; +@@ -612,8 +648,8 @@ static void revalidate_tty(struct aa_label *label) + struct tty_file_private, list); + file = file_priv->file; + +- if (aa_file_perm(OP_INHERIT, label, file, MAY_READ | MAY_WRITE, +- IN_ATOMIC)) ++ if (aa_file_perm(OP_INHERIT, subj_cred, label, file, ++ MAY_READ | MAY_WRITE, IN_ATOMIC)) + drop_tty = 1; + } + spin_unlock(&tty->files_lock); +@@ -623,12 +659,17 @@ static void revalidate_tty(struct aa_label *label) + no_tty(); + } + ++struct cred_label { ++ const struct cred *cred; ++ struct aa_label *label; ++}; ++ + static int match_file(const void *p, struct file *file, unsigned int fd) + { +- struct aa_label *label = (struct aa_label *)p; ++ struct cred_label *cl = (struct cred_label *)p; + +- if (aa_file_perm(OP_INHERIT, label, file, aa_map_file_to_perms(file), +- IN_ATOMIC)) ++ if (aa_file_perm(OP_INHERIT, cl->cred, cl->label, file, ++ aa_map_file_to_perms(file), IN_ATOMIC)) + return fd + 1; + return 0; + } +@@ -638,13 +679,17 @@ static int match_file(const void *p, struct file *file, unsigned int fd) + void aa_inherit_files(const struct cred *cred, struct files_struct *files) + { + struct aa_label *label = aa_get_newest_cred_label(cred); ++ struct cred_label cl = { ++ .cred = cred, ++ .label = label, ++ }; + struct file *devnull = NULL; + unsigned int n; + +- revalidate_tty(label); ++ revalidate_tty(cred, label); + + /* Revalidate access to inherited open files. */ +- n = iterate_fd(files, 0, match_file, label); ++ n = iterate_fd(files, 0, match_file, &cl); + if (!n) /* none found? */ + goto out; + +@@ -654,7 +699,7 @@ void aa_inherit_files(const struct cred *cred, struct files_struct *files) + /* replace all the matching ones with this */ + do { + replace_fd(n - 1, devnull, 0); +- } while ((n = iterate_fd(files, n, match_file, label)) != 0); ++ } while ((n = iterate_fd(files, n, match_file, &cl)) != 0); + if (devnull) + fput(devnull); + out: +diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h +index 096f0a04af87f..42d701fec5a6d 100644 +--- a/security/apparmor/include/audit.h ++++ b/security/apparmor/include/audit.h +@@ -109,6 +109,7 @@ struct apparmor_audit_data { + int type; + u16 class; + const char *op; ++ const struct cred *subj_cred; + struct aa_label *subj_label; + const char *name; + const char *info; +diff --git a/security/apparmor/include/capability.h b/security/apparmor/include/capability.h +index d420e2d10b31b..d6dcc604ec0cc 100644 +--- a/security/apparmor/include/capability.h ++++ b/security/apparmor/include/capability.h +@@ -36,7 +36,8 @@ struct aa_caps { + + extern struct aa_sfs_entry aa_sfs_entry_caps[]; + +-int aa_capable(struct aa_label *label, int cap, unsigned int opts); ++int aa_capable(const struct cred *subj_cred, struct aa_label *label, ++ int cap, unsigned int opts); + + static inline void aa_free_cap_rules(struct aa_caps *caps) + { +diff --git a/security/apparmor/include/file.h b/security/apparmor/include/file.h +index 5be620af33ba0..64dc6d1a7a05c 100644 +--- a/security/apparmor/include/file.h ++++ b/security/apparmor/include/file.h +@@ -108,7 +108,8 @@ struct path_cond { + + #define COMBINED_PERM_MASK(X) ((X).allow | (X).audit | (X).quiet | (X).kill) + +-int aa_audit_file(struct aa_profile *profile, struct aa_perms *perms, ++int aa_audit_file(const struct cred *cred, ++ struct aa_profile *profile, struct aa_perms *perms, + const char *op, u32 request, const char *name, + const char *target, struct aa_label *tlabel, kuid_t ouid, + const char *info, int error); +@@ -119,14 +120,16 @@ aa_state_t aa_str_perms(struct aa_policydb *file_rules, aa_state_t start, + const char *name, struct path_cond *cond, + struct aa_perms *perms); + +-int aa_path_perm(const char *op, struct aa_label *label, +- const struct path *path, int flags, u32 request, +- struct path_cond *cond); ++int aa_path_perm(const char *op, const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, ++ int flags, u32 request, struct path_cond *cond); + +-int aa_path_link(struct aa_label *label, struct dentry *old_dentry, +- const struct path *new_dir, struct dentry *new_dentry); ++int aa_path_link(const struct cred *subj_cred, struct aa_label *label, ++ struct dentry *old_dentry, const struct path *new_dir, ++ struct dentry *new_dentry); + +-int aa_file_perm(const char *op, struct aa_label *label, struct file *file, ++int aa_file_perm(const char *op, const struct cred *subj_cred, ++ struct aa_label *label, struct file *file, + u32 request, bool in_atomic); + + void aa_inherit_files(const struct cred *cred, struct files_struct *files); +diff --git a/security/apparmor/include/ipc.h b/security/apparmor/include/ipc.h +index a1ac6ffb95e9c..74d17052f76bc 100644 +--- a/security/apparmor/include/ipc.h ++++ b/security/apparmor/include/ipc.h +@@ -13,6 +13,8 @@ + + #include + +-int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig); ++int aa_may_signal(const struct cred *subj_cred, struct aa_label *sender, ++ const struct cred *target_cred, struct aa_label *target, ++ int sig); + + #endif /* __AA_IPC_H */ +diff --git a/security/apparmor/include/mount.h b/security/apparmor/include/mount.h +index a710683b24965..10c76f906a653 100644 +--- a/security/apparmor/include/mount.h ++++ b/security/apparmor/include/mount.h +@@ -25,26 +25,33 @@ + + #define AA_MS_IGNORE_MASK (MS_KERNMOUNT | MS_NOSEC | MS_ACTIVE | MS_BORN) + +-int aa_remount(struct aa_label *label, const struct path *path, ++int aa_remount(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + unsigned long flags, void *data); + +-int aa_bind_mount(struct aa_label *label, const struct path *path, ++int aa_bind_mount(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + const char *old_name, unsigned long flags); + + +-int aa_mount_change_type(struct aa_label *label, const struct path *path, ++int aa_mount_change_type(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + unsigned long flags); + +-int aa_move_mount(struct aa_label *label, const struct path *path, ++int aa_move_mount(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + const char *old_name); + +-int aa_new_mount(struct aa_label *label, const char *dev_name, ++int aa_new_mount(const struct cred *subj_cred, ++ struct aa_label *label, const char *dev_name, + const struct path *path, const char *type, unsigned long flags, + void *data); + +-int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags); ++int aa_umount(const struct cred *subj_cred, ++ struct aa_label *label, struct vfsmount *mnt, int flags); + +-int aa_pivotroot(struct aa_label *label, const struct path *old_path, ++int aa_pivotroot(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *old_path, + const struct path *new_path); + + #endif /* __AA_MOUNT_H */ +diff --git a/security/apparmor/include/net.h b/security/apparmor/include/net.h +index a336e57864e89..aa8515af677f0 100644 +--- a/security/apparmor/include/net.h ++++ b/security/apparmor/include/net.h +@@ -93,7 +93,8 @@ void audit_net_cb(struct audit_buffer *ab, void *va); + int aa_profile_af_perm(struct aa_profile *profile, + struct apparmor_audit_data *ad, + u32 request, u16 family, int type); +-int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, ++int aa_af_perm(const struct cred *subj_cred, struct aa_label *label, ++ const char *op, u32 request, u16 family, + int type, int protocol); + static inline int aa_profile_af_sk_perm(struct aa_profile *profile, + struct apparmor_audit_data *ad, +@@ -105,7 +106,8 @@ static inline int aa_profile_af_sk_perm(struct aa_profile *profile, + } + int aa_sk_perm(const char *op, u32 request, struct sock *sk); + +-int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, ++int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, ++ const char *op, u32 request, + struct socket *sock); + + int apparmor_secmark_check(struct aa_label *label, char *op, u32 request, +diff --git a/security/apparmor/include/policy.h b/security/apparmor/include/policy.h +index 545f791cabdae..fa15a5c7febb8 100644 +--- a/security/apparmor/include/policy.h ++++ b/security/apparmor/include/policy.h +@@ -370,9 +370,12 @@ static inline int AUDIT_MODE(struct aa_profile *profile) + return profile->audit; + } + +-bool aa_policy_view_capable(struct aa_label *label, struct aa_ns *ns); +-bool aa_policy_admin_capable(struct aa_label *label, struct aa_ns *ns); +-int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, ++bool aa_policy_view_capable(const struct cred *subj_cred, ++ struct aa_label *label, struct aa_ns *ns); ++bool aa_policy_admin_capable(const struct cred *subj_cred, ++ struct aa_label *label, struct aa_ns *ns); ++int aa_may_manage_policy(const struct cred *subj_cred, ++ struct aa_label *label, struct aa_ns *ns, + u32 mask); + bool aa_current_policy_view_capable(struct aa_ns *ns); + bool aa_current_policy_admin_capable(struct aa_ns *ns); +diff --git a/security/apparmor/include/resource.h b/security/apparmor/include/resource.h +index 961d85d328ea9..ad2c0da8e64fc 100644 +--- a/security/apparmor/include/resource.h ++++ b/security/apparmor/include/resource.h +@@ -33,7 +33,8 @@ struct aa_rlimit { + extern struct aa_sfs_entry aa_sfs_entry_rlimit[]; + + int aa_map_resource(int resource); +-int aa_task_setrlimit(struct aa_label *label, struct task_struct *task, ++int aa_task_setrlimit(const struct cred *subj_cred, struct aa_label *label, ++ struct task_struct *task, + unsigned int resource, struct rlimit *new_rlim); + + void __aa_transition_rlimits(struct aa_label *old, struct aa_label *new); +diff --git a/security/apparmor/include/task.h b/security/apparmor/include/task.h +index 13437d62c70f4..29ba55107b7d6 100644 +--- a/security/apparmor/include/task.h ++++ b/security/apparmor/include/task.h +@@ -91,7 +91,8 @@ static inline void aa_clear_task_ctx_trans(struct aa_task_ctx *ctx) + "segv usr2 pipe alrm term stkflt chld cont stop stp ttin ttou urg " \ + "xcpu xfsz vtalrm prof winch io pwr sys emt lost" + +-int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, ++int aa_may_ptrace(const struct cred *tracer_cred, struct aa_label *tracer, ++ const struct cred *tracee_cred, struct aa_label *tracee, + u32 request); + + +diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c +index fd8306399b820..c0d0dbd7b4c4b 100644 +--- a/security/apparmor/ipc.c ++++ b/security/apparmor/ipc.c +@@ -75,7 +75,8 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va) + FLAGS_NONE, GFP_ATOMIC); + } + +-static int profile_signal_perm(struct aa_profile *profile, ++static int profile_signal_perm(const struct cred *cred, ++ struct aa_profile *profile, + struct aa_label *peer, u32 request, + struct apparmor_audit_data *ad) + { +@@ -88,6 +89,7 @@ static int profile_signal_perm(struct aa_profile *profile, + !ANY_RULE_MEDIATES(&profile->rules, AA_CLASS_SIGNAL)) + return 0; + ++ ad->subj_cred = cred; + ad->peer = peer; + /* TODO: secondary cache check */ + state = aa_dfa_next(rules->policy.dfa, +@@ -98,7 +100,9 @@ static int profile_signal_perm(struct aa_profile *profile, + return aa_check_perms(profile, &perms, request, ad, audit_signal_cb); + } + +-int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig) ++int aa_may_signal(const struct cred *subj_cred, struct aa_label *sender, ++ const struct cred *target_cred, struct aa_label *target, ++ int sig) + { + struct aa_profile *profile; + DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_SIGNAL, OP_SIGNAL); +@@ -106,6 +110,8 @@ int aa_may_signal(struct aa_label *sender, struct aa_label *target, int sig) + ad.signal = map_signal_num(sig); + ad.unmappedsig = sig; + return xcheck_labels(sender, target, profile, +- profile_signal_perm(profile, target, MAY_WRITE, &ad), +- profile_signal_perm(profile, sender, MAY_READ, &ad)); ++ profile_signal_perm(subj_cred, profile, target, ++ MAY_WRITE, &ad), ++ profile_signal_perm(target_cred, profile, sender, ++ MAY_READ, &ad)); + } +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index 359fbfbb4a66e..60f95cc4532a8 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -116,15 +116,17 @@ static int apparmor_ptrace_access_check(struct task_struct *child, + unsigned int mode) + { + struct aa_label *tracer, *tracee; ++ const struct cred *cred; + int error; + ++ cred = get_task_cred(child); ++ tracee = cred_label(cred); /* ref count on cred */ + tracer = __begin_current_label_crit_section(); +- tracee = aa_get_task_label(child); +- error = aa_may_ptrace(tracer, tracee, ++ error = aa_may_ptrace(current_cred(), tracer, cred, tracee, + (mode & PTRACE_MODE_READ) ? AA_PTRACE_READ + : AA_PTRACE_TRACE); +- aa_put_label(tracee); + __end_current_label_crit_section(tracer); ++ put_cred(cred); + + return error; + } +@@ -132,12 +134,15 @@ static int apparmor_ptrace_access_check(struct task_struct *child, + static int apparmor_ptrace_traceme(struct task_struct *parent) + { + struct aa_label *tracer, *tracee; ++ const struct cred *cred; + int error; + + tracee = __begin_current_label_crit_section(); +- tracer = aa_get_task_label(parent); +- error = aa_may_ptrace(tracer, tracee, AA_PTRACE_TRACE); +- aa_put_label(tracer); ++ cred = get_task_cred(parent); ++ tracer = cred_label(cred); /* ref count on cred */ ++ error = aa_may_ptrace(cred, tracer, current_cred(), tracee, ++ AA_PTRACE_TRACE); ++ put_cred(cred); + __end_current_label_crit_section(tracee); + + return error; +@@ -188,7 +193,7 @@ static int apparmor_capable(const struct cred *cred, struct user_namespace *ns, + + label = aa_get_newest_cred_label(cred); + if (!unconfined(label)) +- error = aa_capable(label, cap, opts); ++ error = aa_capable(cred, label, cap, opts); + aa_put_label(label); + + return error; +@@ -211,7 +216,8 @@ static int common_perm(const char *op, const struct path *path, u32 mask, + + label = __begin_current_label_crit_section(); + if (!unconfined(label)) +- error = aa_path_perm(op, label, path, 0, mask, cond); ++ error = aa_path_perm(op, current_cred(), label, path, 0, mask, ++ cond); + __end_current_label_crit_section(label); + + return error; +@@ -357,7 +363,8 @@ static int apparmor_path_link(struct dentry *old_dentry, const struct path *new_ + + label = begin_current_label_crit_section(); + if (!unconfined(label)) +- error = aa_path_link(label, old_dentry, new_dir, new_dentry); ++ error = aa_path_link(current_cred(), label, old_dentry, new_dir, ++ new_dentry); + end_current_label_crit_section(label); + + return error; +@@ -396,23 +403,27 @@ static int apparmor_path_rename(const struct path *old_dir, struct dentry *old_d + vfsuid = i_uid_into_vfsuid(idmap, d_backing_inode(old_dentry)); + cond_exchange.uid = vfsuid_into_kuid(vfsuid); + +- error = aa_path_perm(OP_RENAME_SRC, label, &new_path, 0, ++ error = aa_path_perm(OP_RENAME_SRC, current_cred(), ++ label, &new_path, 0, + MAY_READ | AA_MAY_GETATTR | MAY_WRITE | + AA_MAY_SETATTR | AA_MAY_DELETE, + &cond_exchange); + if (!error) +- error = aa_path_perm(OP_RENAME_DEST, label, &old_path, ++ error = aa_path_perm(OP_RENAME_DEST, current_cred(), ++ label, &old_path, + 0, MAY_WRITE | AA_MAY_SETATTR | + AA_MAY_CREATE, &cond_exchange); + } + + if (!error) +- error = aa_path_perm(OP_RENAME_SRC, label, &old_path, 0, ++ error = aa_path_perm(OP_RENAME_SRC, current_cred(), ++ label, &old_path, 0, + MAY_READ | AA_MAY_GETATTR | MAY_WRITE | + AA_MAY_SETATTR | AA_MAY_DELETE, + &cond); + if (!error) +- error = aa_path_perm(OP_RENAME_DEST, label, &new_path, ++ error = aa_path_perm(OP_RENAME_DEST, current_cred(), ++ label, &new_path, + 0, MAY_WRITE | AA_MAY_SETATTR | + AA_MAY_CREATE, &cond); + +@@ -467,7 +478,8 @@ static int apparmor_file_open(struct file *file) + vfsuid = i_uid_into_vfsuid(idmap, inode); + cond.uid = vfsuid_into_kuid(vfsuid); + +- error = aa_path_perm(OP_OPEN, label, &file->f_path, 0, ++ error = aa_path_perm(OP_OPEN, file->f_cred, ++ label, &file->f_path, 0, + aa_map_file_to_perms(file), &cond); + /* todo cache full allowed permissions set and state */ + fctx->allow = aa_map_file_to_perms(file); +@@ -507,7 +519,7 @@ static int common_file_perm(const char *op, struct file *file, u32 mask, + return -EACCES; + + label = __begin_current_label_crit_section(); +- error = aa_file_perm(op, label, file, mask, in_atomic); ++ error = aa_file_perm(op, current_cred(), label, file, mask, in_atomic); + __end_current_label_crit_section(label); + + return error; +@@ -585,17 +597,21 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path, + label = __begin_current_label_crit_section(); + if (!unconfined(label)) { + if (flags & MS_REMOUNT) +- error = aa_remount(label, path, flags, data); ++ error = aa_remount(current_cred(), label, path, flags, ++ data); + else if (flags & MS_BIND) +- error = aa_bind_mount(label, path, dev_name, flags); ++ error = aa_bind_mount(current_cred(), label, path, ++ dev_name, flags); + else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | + MS_UNBINDABLE)) +- error = aa_mount_change_type(label, path, flags); ++ error = aa_mount_change_type(current_cred(), label, ++ path, flags); + else if (flags & MS_MOVE) +- error = aa_move_mount(label, path, dev_name); ++ error = aa_move_mount(current_cred(), label, path, ++ dev_name); + else +- error = aa_new_mount(label, dev_name, path, type, +- flags, data); ++ error = aa_new_mount(current_cred(), label, dev_name, ++ path, type, flags, data); + } + __end_current_label_crit_section(label); + +@@ -609,7 +625,7 @@ static int apparmor_sb_umount(struct vfsmount *mnt, int flags) + + label = __begin_current_label_crit_section(); + if (!unconfined(label)) +- error = aa_umount(label, mnt, flags); ++ error = aa_umount(current_cred(), label, mnt, flags); + __end_current_label_crit_section(label); + + return error; +@@ -623,7 +639,7 @@ static int apparmor_sb_pivotroot(const struct path *old_path, + + label = aa_get_current_label(); + if (!unconfined(label)) +- error = aa_pivotroot(label, old_path, new_path); ++ error = aa_pivotroot(current_cred(), label, old_path, new_path); + aa_put_label(label); + + return error; +@@ -785,7 +801,8 @@ static int apparmor_task_setrlimit(struct task_struct *task, + int error = 0; + + if (!unconfined(label)) +- error = aa_task_setrlimit(label, task, resource, new_rlim); ++ error = aa_task_setrlimit(current_cred(), label, task, ++ resource, new_rlim); + __end_current_label_crit_section(label); + + return error; +@@ -794,26 +811,27 @@ static int apparmor_task_setrlimit(struct task_struct *task, + static int apparmor_task_kill(struct task_struct *target, struct kernel_siginfo *info, + int sig, const struct cred *cred) + { ++ const struct cred *tc; + struct aa_label *cl, *tl; + int error; + ++ tc = get_task_cred(target); ++ tl = aa_get_newest_cred_label(tc); + if (cred) { + /* + * Dealing with USB IO specific behavior + */ + cl = aa_get_newest_cred_label(cred); +- tl = aa_get_task_label(target); +- error = aa_may_signal(cl, tl, sig); ++ error = aa_may_signal(cred, cl, tc, tl, sig); + aa_put_label(cl); +- aa_put_label(tl); + return error; ++ } else { ++ cl = __begin_current_label_crit_section(); ++ error = aa_may_signal(current_cred(), cl, tc, tl, sig); ++ __end_current_label_crit_section(cl); + } +- +- cl = __begin_current_label_crit_section(); +- tl = aa_get_task_label(target); +- error = aa_may_signal(cl, tl, sig); + aa_put_label(tl); +- __end_current_label_crit_section(cl); ++ put_cred(tc); + + return error; + } +@@ -879,7 +897,8 @@ static int apparmor_socket_create(int family, int type, int protocol, int kern) + if (!(kern || unconfined(label))) + error = af_select(family, + create_perm(label, family, type, protocol), +- aa_af_perm(label, OP_CREATE, AA_MAY_CREATE, ++ aa_af_perm(current_cred(), label, ++ OP_CREATE, AA_MAY_CREATE, + family, type, protocol)); + end_current_label_crit_section(label); + +diff --git a/security/apparmor/mount.c b/security/apparmor/mount.c +index 3830bceff9c8b..2bb77aacc49ae 100644 +--- a/security/apparmor/mount.c ++++ b/security/apparmor/mount.c +@@ -113,6 +113,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) + + /** + * audit_mount - handle the auditing of mount operations ++ * @subj_cred: cred of the subject + * @profile: the profile being enforced (NOT NULL) + * @op: operation being mediated (NOT NULL) + * @name: name of object being mediated (MAYBE NULL) +@@ -128,7 +129,8 @@ static void audit_cb(struct audit_buffer *ab, void *va) + * + * Returns: %0 or error on failure + */ +-static int audit_mount(struct aa_profile *profile, const char *op, ++static int audit_mount(const struct cred *subj_cred, ++ struct aa_profile *profile, const char *op, + const char *name, const char *src_name, + const char *type, const char *trans, + unsigned long flags, const void *data, u32 request, +@@ -166,6 +168,7 @@ static int audit_mount(struct aa_profile *profile, const char *op, + return error; + } + ++ ad.subj_cred = subj_cred; + ad.name = name; + ad.mnt.src_name = src_name; + ad.mnt.type = type; +@@ -284,6 +287,7 @@ static int path_flags(struct aa_profile *profile, const struct path *path) + + /** + * match_mnt_path_str - handle path matching for mount ++ * @subj_cred: cred of confined subject + * @profile: the confining profile + * @mntpath: for the mntpnt (NOT NULL) + * @buffer: buffer to be used to lookup mntpath +@@ -296,7 +300,8 @@ static int path_flags(struct aa_profile *profile, const struct path *path) + * + * Returns: 0 on success else error + */ +-static int match_mnt_path_str(struct aa_profile *profile, ++static int match_mnt_path_str(const struct cred *subj_cred, ++ struct aa_profile *profile, + const struct path *mntpath, char *buffer, + const char *devname, const char *type, + unsigned long flags, void *data, bool binary, +@@ -337,12 +342,14 @@ static int match_mnt_path_str(struct aa_profile *profile, + error = 0; + + audit: +- return audit_mount(profile, OP_MOUNT, mntpnt, devname, type, NULL, ++ return audit_mount(subj_cred, profile, OP_MOUNT, mntpnt, devname, ++ type, NULL, + flags, data, AA_MAY_MOUNT, &perms, info, error); + } + + /** + * match_mnt - handle path matching for mount ++ * @subj_cred: cred of the subject + * @profile: the confining profile + * @path: for the mntpnt (NOT NULL) + * @buffer: buffer to be used to lookup mntpath +@@ -355,7 +362,8 @@ static int match_mnt_path_str(struct aa_profile *profile, + * + * Returns: 0 on success else error + */ +-static int match_mnt(struct aa_profile *profile, const struct path *path, ++static int match_mnt(const struct cred *subj_cred, ++ struct aa_profile *profile, const struct path *path, + char *buffer, const struct path *devpath, char *devbuffer, + const char *type, unsigned long flags, void *data, + bool binary) +@@ -379,11 +387,12 @@ static int match_mnt(struct aa_profile *profile, const struct path *path, + devname = ERR_PTR(error); + } + +- return match_mnt_path_str(profile, path, buffer, devname, type, flags, +- data, binary, info); ++ return match_mnt_path_str(subj_cred, profile, path, buffer, devname, ++ type, flags, data, binary, info); + } + +-int aa_remount(struct aa_label *label, const struct path *path, ++int aa_remount(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + unsigned long flags, void *data) + { + struct aa_profile *profile; +@@ -400,14 +409,16 @@ int aa_remount(struct aa_label *label, const struct path *path, + if (!buffer) + return -ENOMEM; + error = fn_for_each_confined(label, profile, +- match_mnt(profile, path, buffer, NULL, NULL, NULL, ++ match_mnt(subj_cred, profile, path, buffer, NULL, ++ NULL, NULL, + flags, data, binary)); + aa_put_buffer(buffer); + + return error; + } + +-int aa_bind_mount(struct aa_label *label, const struct path *path, ++int aa_bind_mount(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + const char *dev_name, unsigned long flags) + { + struct aa_profile *profile; +@@ -434,8 +445,8 @@ int aa_bind_mount(struct aa_label *label, const struct path *path, + goto out; + + error = fn_for_each_confined(label, profile, +- match_mnt(profile, path, buffer, &old_path, old_buffer, +- NULL, flags, NULL, false)); ++ match_mnt(subj_cred, profile, path, buffer, &old_path, ++ old_buffer, NULL, flags, NULL, false)); + out: + aa_put_buffer(buffer); + aa_put_buffer(old_buffer); +@@ -444,7 +455,8 @@ int aa_bind_mount(struct aa_label *label, const struct path *path, + return error; + } + +-int aa_mount_change_type(struct aa_label *label, const struct path *path, ++int aa_mount_change_type(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + unsigned long flags) + { + struct aa_profile *profile; +@@ -462,14 +474,16 @@ int aa_mount_change_type(struct aa_label *label, const struct path *path, + if (!buffer) + return -ENOMEM; + error = fn_for_each_confined(label, profile, +- match_mnt(profile, path, buffer, NULL, NULL, NULL, ++ match_mnt(subj_cred, profile, path, buffer, NULL, ++ NULL, NULL, + flags, NULL, false)); + aa_put_buffer(buffer); + + return error; + } + +-int aa_move_mount(struct aa_label *label, const struct path *path, ++int aa_move_mount(const struct cred *subj_cred, ++ struct aa_label *label, const struct path *path, + const char *orig_name) + { + struct aa_profile *profile; +@@ -493,7 +507,8 @@ int aa_move_mount(struct aa_label *label, const struct path *path, + if (!buffer || !old_buffer) + goto out; + error = fn_for_each_confined(label, profile, +- match_mnt(profile, path, buffer, &old_path, old_buffer, ++ match_mnt(subj_cred, profile, path, buffer, &old_path, ++ old_buffer, + NULL, MS_MOVE, NULL, false)); + out: + aa_put_buffer(buffer); +@@ -503,9 +518,9 @@ int aa_move_mount(struct aa_label *label, const struct path *path, + return error; + } + +-int aa_new_mount(struct aa_label *label, const char *dev_name, +- const struct path *path, const char *type, unsigned long flags, +- void *data) ++int aa_new_mount(const struct cred *subj_cred, struct aa_label *label, ++ const char *dev_name, const struct path *path, ++ const char *type, unsigned long flags, void *data) + { + struct aa_profile *profile; + char *buffer = NULL, *dev_buffer = NULL; +@@ -550,12 +565,14 @@ int aa_new_mount(struct aa_label *label, const char *dev_name, + goto out; + } + error = fn_for_each_confined(label, profile, +- match_mnt(profile, path, buffer, dev_path, dev_buffer, ++ match_mnt(subj_cred, profile, path, buffer, ++ dev_path, dev_buffer, + type, flags, data, binary)); + } else { + error = fn_for_each_confined(label, profile, +- match_mnt_path_str(profile, path, buffer, dev_name, +- type, flags, data, binary, NULL)); ++ match_mnt_path_str(subj_cred, profile, path, ++ buffer, dev_name, ++ type, flags, data, binary, NULL)); + } + + out: +@@ -567,7 +584,8 @@ int aa_new_mount(struct aa_label *label, const char *dev_name, + return error; + } + +-static int profile_umount(struct aa_profile *profile, const struct path *path, ++static int profile_umount(const struct cred *subj_cred, ++ struct aa_profile *profile, const struct path *path, + char *buffer) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, +@@ -596,11 +614,13 @@ static int profile_umount(struct aa_profile *profile, const struct path *path, + error = -EACCES; + + audit: +- return audit_mount(profile, OP_UMOUNT, name, NULL, NULL, NULL, 0, NULL, ++ return audit_mount(subj_cred, profile, OP_UMOUNT, name, NULL, NULL, ++ NULL, 0, NULL, + AA_MAY_UMOUNT, &perms, info, error); + } + +-int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags) ++int aa_umount(const struct cred *subj_cred, struct aa_label *label, ++ struct vfsmount *mnt, int flags) + { + struct aa_profile *profile; + char *buffer = NULL; +@@ -615,7 +635,7 @@ int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags) + return -ENOMEM; + + error = fn_for_each_confined(label, profile, +- profile_umount(profile, &path, buffer)); ++ profile_umount(subj_cred, profile, &path, buffer)); + aa_put_buffer(buffer); + + return error; +@@ -625,7 +645,8 @@ int aa_umount(struct aa_label *label, struct vfsmount *mnt, int flags) + * + * Returns: label for transition or ERR_PTR. Does not return NULL + */ +-static struct aa_label *build_pivotroot(struct aa_profile *profile, ++static struct aa_label *build_pivotroot(const struct cred *subj_cred, ++ struct aa_profile *profile, + const struct path *new_path, + char *new_buffer, + const struct path *old_path, +@@ -670,7 +691,8 @@ static struct aa_label *build_pivotroot(struct aa_profile *profile, + error = 0; + + audit: +- error = audit_mount(profile, OP_PIVOTROOT, new_name, old_name, ++ error = audit_mount(subj_cred, profile, OP_PIVOTROOT, new_name, ++ old_name, + NULL, trans_name, 0, NULL, AA_MAY_PIVOTROOT, + &perms, info, error); + if (error) +@@ -679,7 +701,8 @@ static struct aa_label *build_pivotroot(struct aa_profile *profile, + return aa_get_newest_label(&profile->label); + } + +-int aa_pivotroot(struct aa_label *label, const struct path *old_path, ++int aa_pivotroot(const struct cred *subj_cred, struct aa_label *label, ++ const struct path *old_path, + const struct path *new_path) + { + struct aa_profile *profile; +@@ -697,7 +720,8 @@ int aa_pivotroot(struct aa_label *label, const struct path *old_path, + if (!old_buffer || !new_buffer) + goto out; + target = fn_label_build(label, profile, GFP_KERNEL, +- build_pivotroot(profile, new_path, new_buffer, ++ build_pivotroot(subj_cred, profile, new_path, ++ new_buffer, + old_path, old_buffer)); + if (!target) { + info = "label build failed"; +@@ -723,7 +747,8 @@ int aa_pivotroot(struct aa_label *label, const struct path *old_path, + fail: + /* TODO: add back in auditing of new_name and old_name */ + error = fn_for_each(label, profile, +- audit_mount(profile, OP_PIVOTROOT, NULL /*new_name */, ++ audit_mount(subj_cred, profile, OP_PIVOTROOT, ++ NULL /*new_name */, + NULL /* old_name */, + NULL, NULL, + 0, NULL, AA_MAY_PIVOTROOT, &nullperms, info, +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 5e50f80e35db0..704c171232ab4 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -135,8 +135,8 @@ int aa_profile_af_perm(struct aa_profile *profile, + return aa_check_perms(profile, &perms, request, ad, audit_net_cb); + } + +-int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, +- int type, int protocol) ++int aa_af_perm(const struct cred *subj_cred, struct aa_label *label, ++ const char *op, u32 request, u16 family, int type, int protocol) + { + struct aa_profile *profile; + DEFINE_AUDIT_NET(ad, op, NULL, family, type, protocol); +@@ -146,7 +146,9 @@ int aa_af_perm(struct aa_label *label, const char *op, u32 request, u16 family, + type)); + } + +-static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, ++static int aa_label_sk_perm(const struct cred *subj_cred, ++ struct aa_label *label, ++ const char *op, u32 request, + struct sock *sk) + { + struct aa_sk_ctx *ctx = SK_CTX(sk); +@@ -159,6 +161,7 @@ static int aa_label_sk_perm(struct aa_label *label, const char *op, u32 request, + struct aa_profile *profile; + DEFINE_AUDIT_SK(ad, op, sk); + ++ ad.subj_cred = subj_cred; + error = fn_for_each_confined(label, profile, + aa_profile_af_sk_perm(profile, &ad, request, sk)); + } +@@ -176,21 +179,21 @@ int aa_sk_perm(const char *op, u32 request, struct sock *sk) + + /* TODO: switch to begin_current_label ???? */ + label = begin_current_label_crit_section(); +- error = aa_label_sk_perm(label, op, request, sk); ++ error = aa_label_sk_perm(current_cred(), label, op, request, sk); + end_current_label_crit_section(label); + + return error; + } + + +-int aa_sock_file_perm(struct aa_label *label, const char *op, u32 request, +- struct socket *sock) ++int aa_sock_file_perm(const struct cred *subj_cred, struct aa_label *label, ++ const char *op, u32 request, struct socket *sock) + { + AA_BUG(!label); + AA_BUG(!sock); + AA_BUG(!sock->sk); + +- return aa_label_sk_perm(label, op, request, sock->sk); ++ return aa_label_sk_perm(subj_cred, label, op, request, sock->sk); + } + + #ifdef CONFIG_NETWORK_SECMARK +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index e5f1ef83b0fda..8a07793ce1032 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -762,21 +762,23 @@ static int audit_policy(struct aa_label *subj_label, const char *op, + /* don't call out to other LSMs in the stack for apparmor policy admin + * permissions + */ +-static int policy_ns_capable(struct aa_label *label, ++static int policy_ns_capable(const struct cred *subj_cred, ++ struct aa_label *label, + struct user_namespace *userns, int cap) + { + int err; + + /* check for MAC_ADMIN cap in cred */ +- err = cap_capable(current_cred(), userns, cap, CAP_OPT_NONE); ++ err = cap_capable(subj_cred, userns, cap, CAP_OPT_NONE); + if (!err) +- err = aa_capable(label, cap, CAP_OPT_NONE); ++ err = aa_capable(subj_cred, label, cap, CAP_OPT_NONE); + + return err; + } + + /** + * aa_policy_view_capable - check if viewing policy in at @ns is allowed ++ * @subj_cred: cred of subject + * @label: label that is trying to view policy in ns + * @ns: namespace being viewed by @label (may be NULL if @label's ns) + * +@@ -785,9 +787,10 @@ static int policy_ns_capable(struct aa_label *label, + * If @ns is NULL then the namespace being viewed is assumed to be the + * tasks current namespace. + */ +-bool aa_policy_view_capable(struct aa_label *label, struct aa_ns *ns) ++bool aa_policy_view_capable(const struct cred *subj_cred, ++ struct aa_label *label, struct aa_ns *ns) + { +- struct user_namespace *user_ns = current_user_ns(); ++ struct user_namespace *user_ns = subj_cred->user_ns; + struct aa_ns *view_ns = labels_view(label); + bool root_in_user_ns = uid_eq(current_euid(), make_kuid(user_ns, 0)) || + in_egroup_p(make_kgid(user_ns, 0)); +@@ -804,15 +807,17 @@ bool aa_policy_view_capable(struct aa_label *label, struct aa_ns *ns) + return response; + } + +-bool aa_policy_admin_capable(struct aa_label *label, struct aa_ns *ns) ++bool aa_policy_admin_capable(const struct cred *subj_cred, ++ struct aa_label *label, struct aa_ns *ns) + { +- struct user_namespace *user_ns = current_user_ns(); +- bool capable = policy_ns_capable(label, user_ns, CAP_MAC_ADMIN) == 0; ++ struct user_namespace *user_ns = subj_cred->user_ns; ++ bool capable = policy_ns_capable(subj_cred, label, user_ns, ++ CAP_MAC_ADMIN) == 0; + + AA_DEBUG("cap_mac_admin? %d\n", capable); + AA_DEBUG("policy locked? %d\n", aa_g_lock_policy); + +- return aa_policy_view_capable(label, ns) && capable && ++ return aa_policy_view_capable(subj_cred, label, ns) && capable && + !aa_g_lock_policy; + } + +@@ -822,7 +827,7 @@ bool aa_current_policy_view_capable(struct aa_ns *ns) + bool res; + + label = __begin_current_label_crit_section(); +- res = aa_policy_view_capable(label, ns); ++ res = aa_policy_view_capable(current_cred(), label, ns); + __end_current_label_crit_section(label); + + return res; +@@ -834,7 +839,7 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns) + bool res; + + label = __begin_current_label_crit_section(); +- res = aa_policy_admin_capable(label, ns); ++ res = aa_policy_admin_capable(current_cred(), label, ns); + __end_current_label_crit_section(label); + + return res; +@@ -842,13 +847,15 @@ bool aa_current_policy_admin_capable(struct aa_ns *ns) + + /** + * aa_may_manage_policy - can the current task manage policy ++ * @subj_cred; subjects cred + * @label: label to check if it can manage policy + * @ns: namespace being managed by @label (may be NULL if @label's ns) + * @mask: contains the policy manipulation operation being done + * + * Returns: 0 if the task is allowed to manipulate policy else error + */ +-int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask) ++int aa_may_manage_policy(const struct cred *subj_cred, struct aa_label *label, ++ struct aa_ns *ns, u32 mask) + { + const char *op; + +@@ -864,7 +871,7 @@ int aa_may_manage_policy(struct aa_label *label, struct aa_ns *ns, u32 mask) + return audit_policy(label, op, NULL, NULL, "policy_locked", + -EACCES); + +- if (!aa_policy_admin_capable(label, ns)) ++ if (!aa_policy_admin_capable(subj_cred, label, ns)) + return audit_policy(label, op, NULL, NULL, "not policy admin", + -EACCES); + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index 73ba26c646a5e..dcc94c3153d51 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -43,6 +43,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) + + /** + * audit_resource - audit setting resource limit ++ * @subj_cred: cred setting the resource + * @profile: profile being enforced (NOT NULL) + * @resource: rlimit being auditing + * @value: value being set +@@ -52,13 +53,15 @@ static void audit_cb(struct audit_buffer *ab, void *va) + * + * Returns: 0 or ad->error else other error code on failure + */ +-static int audit_resource(struct aa_profile *profile, unsigned int resource, ++static int audit_resource(const struct cred *subj_cred, ++ struct aa_profile *profile, unsigned int resource, + unsigned long value, struct aa_label *peer, + const char *info, int error) + { + DEFINE_AUDIT_DATA(ad, LSM_AUDIT_DATA_NONE, AA_CLASS_RLIMITS, + OP_SETRLIMIT); + ++ ad.subj_cred = subj_cred; + ad.rlim.rlim = resource; + ad.rlim.max = value; + ad.peer = peer; +@@ -82,7 +85,8 @@ int aa_map_resource(int resource) + return rlim_map[resource]; + } + +-static int profile_setrlimit(struct aa_profile *profile, unsigned int resource, ++static int profile_setrlimit(const struct cred *subj_cred, ++ struct aa_profile *profile, unsigned int resource, + struct rlimit *new_rlim) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, +@@ -92,12 +96,13 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource, + if (rules->rlimits.mask & (1 << resource) && new_rlim->rlim_max > + rules->rlimits.limits[resource].rlim_max) + e = -EACCES; +- return audit_resource(profile, resource, new_rlim->rlim_max, NULL, NULL, +- e); ++ return audit_resource(subj_cred, profile, resource, new_rlim->rlim_max, ++ NULL, NULL, e); + } + + /** + * aa_task_setrlimit - test permission to set an rlimit ++ * @subj_cred: cred setting the limit + * @label: label confining the task (NOT NULL) + * @task: task the resource is being set on + * @resource: the resource being set +@@ -107,7 +112,8 @@ static int profile_setrlimit(struct aa_profile *profile, unsigned int resource, + * + * Returns: 0 or error code if setting resource failed + */ +-int aa_task_setrlimit(struct aa_label *label, struct task_struct *task, ++int aa_task_setrlimit(const struct cred *subj_cred, struct aa_label *label, ++ struct task_struct *task, + unsigned int resource, struct rlimit *new_rlim) + { + struct aa_profile *profile; +@@ -126,14 +132,15 @@ int aa_task_setrlimit(struct aa_label *label, struct task_struct *task, + */ + + if (label != peer && +- aa_capable(label, CAP_SYS_RESOURCE, CAP_OPT_NOAUDIT) != 0) ++ aa_capable(subj_cred, label, CAP_SYS_RESOURCE, CAP_OPT_NOAUDIT) != 0) + error = fn_for_each(label, profile, +- audit_resource(profile, resource, ++ audit_resource(subj_cred, profile, resource, + new_rlim->rlim_max, peer, + "cap_sys_resource", -EACCES)); + else + error = fn_for_each_confined(label, profile, +- profile_setrlimit(profile, resource, new_rlim)); ++ profile_setrlimit(subj_cred, profile, resource, ++ new_rlim)); + aa_put_label(peer); + + return error; +diff --git a/security/apparmor/task.c b/security/apparmor/task.c +index 79850e8321420..0d7af707cccdd 100644 +--- a/security/apparmor/task.c ++++ b/security/apparmor/task.c +@@ -226,14 +226,16 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va) + + /* assumes check for RULE_MEDIATES is already done */ + /* TODO: conditionals */ +-static int profile_ptrace_perm(struct aa_profile *profile, +- struct aa_label *peer, u32 request, +- struct apparmor_audit_data *ad) ++static int profile_ptrace_perm(const struct cred *cred, ++ struct aa_profile *profile, ++ struct aa_label *peer, u32 request, ++ struct apparmor_audit_data *ad) + { + struct aa_ruleset *rules = list_first_entry(&profile->rules, + typeof(*rules), list); + struct aa_perms perms = { }; + ++ ad->subj_cred = cred; + ad->peer = peer; + aa_profile_match_label(profile, rules, peer, AA_CLASS_PTRACE, request, + &perms); +@@ -241,7 +243,8 @@ static int profile_ptrace_perm(struct aa_profile *profile, + return aa_check_perms(profile, &perms, request, ad, audit_ptrace_cb); + } + +-static int profile_tracee_perm(struct aa_profile *tracee, ++static int profile_tracee_perm(const struct cred *cred, ++ struct aa_profile *tracee, + struct aa_label *tracer, u32 request, + struct apparmor_audit_data *ad) + { +@@ -249,10 +252,11 @@ static int profile_tracee_perm(struct aa_profile *tracee, + !ANY_RULE_MEDIATES(&tracee->rules, AA_CLASS_PTRACE)) + return 0; + +- return profile_ptrace_perm(tracee, tracer, request, ad); ++ return profile_ptrace_perm(cred, tracee, tracer, request, ad); + } + +-static int profile_tracer_perm(struct aa_profile *tracer, ++static int profile_tracer_perm(const struct cred *cred, ++ struct aa_profile *tracer, + struct aa_label *tracee, u32 request, + struct apparmor_audit_data *ad) + { +@@ -260,7 +264,7 @@ static int profile_tracer_perm(struct aa_profile *tracer, + return 0; + + if (ANY_RULE_MEDIATES(&tracer->rules, AA_CLASS_PTRACE)) +- return profile_ptrace_perm(tracer, tracee, request, ad); ++ return profile_ptrace_perm(cred, tracer, tracee, request, ad); + + /* profile uses the old style capability check for ptrace */ + if (&tracer->label == tracee) +@@ -269,8 +273,8 @@ static int profile_tracer_perm(struct aa_profile *tracer, + ad->subj_label = &tracer->label; + ad->peer = tracee; + ad->request = 0; +- ad->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, +- CAP_OPT_NONE); ++ ad->error = aa_capable(cred, &tracer->label, CAP_SYS_PTRACE, ++ CAP_OPT_NONE); + + return aa_audit(AUDIT_APPARMOR_AUTO, tracer, ad, audit_ptrace_cb); + } +@@ -283,7 +287,8 @@ static int profile_tracer_perm(struct aa_profile *tracer, + * + * Returns: %0 else error code if permission denied or error + */ +-int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, ++int aa_may_ptrace(const struct cred *tracer_cred, struct aa_label *tracer, ++ const struct cred *tracee_cred, struct aa_label *tracee, + u32 request) + { + struct aa_profile *profile; +@@ -291,6 +296,8 @@ int aa_may_ptrace(struct aa_label *tracer, struct aa_label *tracee, + DEFINE_AUDIT_DATA(sa, LSM_AUDIT_DATA_NONE, AA_CLASS_PTRACE, OP_PTRACE); + + return xcheck_labels(tracer, tracee, profile, +- profile_tracer_perm(profile, tracee, request, &sa), +- profile_tracee_perm(profile, tracer, xrequest, &sa)); ++ profile_tracer_perm(tracer_cred, profile, tracee, ++ request, &sa), ++ profile_tracee_perm(tracee_cred, profile, tracer, ++ xrequest, &sa)); + } +-- +2.42.0 + diff --git a/queue-6.6/apparmor-rename-audit_data-label-to-audit_data-subj_.patch b/queue-6.6/apparmor-rename-audit_data-label-to-audit_data-subj_.patch new file mode 100644 index 00000000000..7c4a7febc2c --- /dev/null +++ b/queue-6.6/apparmor-rename-audit_data-label-to-audit_data-subj_.patch @@ -0,0 +1,223 @@ +From 1df12c1710f6af2f580f6cffecd20d981358a372 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 19 Sep 2022 00:46:09 -0700 +Subject: apparmor: rename audit_data->label to audit_data->subj_label + +From: John Johansen + +[ Upstream commit d20f5a1a6e792d22199c9989ec7ab9e95c48d60c ] + +rename audit_data's label field to subj_label to better reflect its +use. Also at the same time drop unneeded assignments to ->subj_label +as the later call to aa_check_perms will do the assignment if needed. + +Reviewed-by: Georgia Garcia +Signed-off-by: John Johansen +Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation") +Signed-off-by: Sasha Levin +--- + security/apparmor/audit.c | 6 +++--- + security/apparmor/file.c | 2 +- + security/apparmor/include/audit.h | 2 +- + security/apparmor/ipc.c | 2 +- + security/apparmor/lib.c | 5 ++--- + security/apparmor/lsm.c | 4 ++-- + security/apparmor/net.c | 2 +- + security/apparmor/policy.c | 6 +++--- + security/apparmor/resource.c | 2 +- + security/apparmor/task.c | 4 ++-- + 10 files changed, 17 insertions(+), 18 deletions(-) + +diff --git a/security/apparmor/audit.c b/security/apparmor/audit.c +index 06ad6a8fcce18..6933cb2f679b0 100644 +--- a/security/apparmor/audit.c ++++ b/security/apparmor/audit.c +@@ -113,8 +113,8 @@ static void audit_pre(struct audit_buffer *ab, void *va) + audit_log_format(ab, " error=%d", ad->error); + } + +- if (ad->label) { +- struct aa_label *label = ad->label; ++ if (ad->subj_label) { ++ struct aa_label *label = ad->subj_label; + + if (label_isprofile(label)) { + struct aa_profile *profile = labels_profile(label); +@@ -187,7 +187,7 @@ int aa_audit(int type, struct aa_profile *profile, + if (KILL_MODE(profile) && type == AUDIT_APPARMOR_DENIED) + type = AUDIT_APPARMOR_KILL; + +- ad->label = &profile->label; ++ ad->subj_label = &profile->label; + + aa_audit_msg(type, ad, cb); + +diff --git a/security/apparmor/file.c b/security/apparmor/file.c +index 9ea95fa18e7d5..5bfa70a972071 100644 +--- a/security/apparmor/file.c ++++ b/security/apparmor/file.c +@@ -67,7 +67,7 @@ static void file_audit_cb(struct audit_buffer *ab, void *va) + + if (ad->peer) { + audit_log_format(ab, " target="); +- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, ++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, + FLAG_VIEW_SUBNS, GFP_KERNEL); + } else if (ad->fs.target) { + audit_log_format(ab, " target="); +diff --git a/security/apparmor/include/audit.h b/security/apparmor/include/audit.h +index 85931ec94e916..096f0a04af87f 100644 +--- a/security/apparmor/include/audit.h ++++ b/security/apparmor/include/audit.h +@@ -109,7 +109,7 @@ struct apparmor_audit_data { + int type; + u16 class; + const char *op; +- struct aa_label *label; ++ struct aa_label *subj_label; + const char *name; + const char *info; + u32 request; +diff --git a/security/apparmor/ipc.c b/security/apparmor/ipc.c +index f198b8d620a4f..fd8306399b820 100644 +--- a/security/apparmor/ipc.c ++++ b/security/apparmor/ipc.c +@@ -71,7 +71,7 @@ static void audit_signal_cb(struct audit_buffer *ab, void *va) + audit_log_format(ab, " signal=rtmin+%d", + ad->signal - SIGRT_BASE); + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, ++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + +diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c +index d6b2750fd72e4..c87bccafff446 100644 +--- a/security/apparmor/lib.c ++++ b/security/apparmor/lib.c +@@ -297,7 +297,7 @@ static void aa_audit_perms_cb(struct audit_buffer *ab, void *va) + PERMS_NAMES_MASK); + } + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, ++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + +@@ -357,7 +357,6 @@ int aa_profile_label_perm(struct aa_profile *profile, struct aa_profile *target, + typeof(*rules), list); + struct aa_perms perms; + +- ad->label = &profile->label; + ad->peer = &target->label; + ad->request = request; + +@@ -419,7 +418,7 @@ int aa_check_perms(struct aa_profile *profile, struct aa_perms *perms, + } + + if (ad) { +- ad->label = &profile->label; ++ ad->subj_label = &profile->label; + ad->request = request; + ad->denied = denied; + ad->error = error; +diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c +index fd7852a4737c7..359fbfbb4a66e 100644 +--- a/security/apparmor/lsm.c ++++ b/security/apparmor/lsm.c +@@ -722,11 +722,11 @@ static int apparmor_setprocattr(const char *name, void *value, + return error; + + fail: +- ad.label = begin_current_label_crit_section(); ++ ad.subj_label = begin_current_label_crit_section(); + ad.info = name; + ad.error = error = -EINVAL; + aa_audit_msg(AUDIT_APPARMOR_DENIED, &ad, NULL); +- end_current_label_crit_section(ad.label); ++ end_current_label_crit_section(ad.subj_label); + goto out; + } + +diff --git a/security/apparmor/net.c b/security/apparmor/net.c +index 0c7304cd479c5..5e50f80e35db0 100644 +--- a/security/apparmor/net.c ++++ b/security/apparmor/net.c +@@ -100,7 +100,7 @@ void audit_net_cb(struct audit_buffer *ab, void *va) + } + if (ad->peer) { + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, ++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + } +diff --git a/security/apparmor/policy.c b/security/apparmor/policy.c +index 9a7dbe64f102b..e5f1ef83b0fda 100644 +--- a/security/apparmor/policy.c ++++ b/security/apparmor/policy.c +@@ -733,7 +733,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) + + /** + * audit_policy - Do auditing of policy changes +- * @label: label to check if it can manage policy ++ * @subj_label: label to check if it can manage policy + * @op: policy operation being performed + * @ns_name: name of namespace being manipulated + * @name: name of profile being manipulated (NOT NULL) +@@ -742,7 +742,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) + * + * Returns: the error to be returned after audit is done + */ +-static int audit_policy(struct aa_label *label, const char *op, ++static int audit_policy(struct aa_label *subj_label, const char *op, + const char *ns_name, const char *name, + const char *info, int error) + { +@@ -752,7 +752,7 @@ static int audit_policy(struct aa_label *label, const char *op, + ad.name = name; + ad.info = info; + ad.error = error; +- ad.label = label; ++ ad.subj_label = subj_label; + + aa_audit_msg(AUDIT_APPARMOR_STATUS, &ad, audit_cb); + +diff --git a/security/apparmor/resource.c b/security/apparmor/resource.c +index b6b5e1bfe9a26..73ba26c646a5e 100644 +--- a/security/apparmor/resource.c ++++ b/security/apparmor/resource.c +@@ -36,7 +36,7 @@ static void audit_cb(struct audit_buffer *ab, void *va) + rlim_names[ad->rlim.rlim], ad->rlim.max); + if (ad->peer) { + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, ++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + } +diff --git a/security/apparmor/task.c b/security/apparmor/task.c +index 8bd1f212215c4..79850e8321420 100644 +--- a/security/apparmor/task.c ++++ b/security/apparmor/task.c +@@ -220,7 +220,7 @@ static void audit_ptrace_cb(struct audit_buffer *ab, void *va) + } + } + audit_log_format(ab, " peer="); +- aa_label_xaudit(ab, labels_ns(ad->label), ad->peer, ++ aa_label_xaudit(ab, labels_ns(ad->subj_label), ad->peer, + FLAGS_NONE, GFP_ATOMIC); + } + +@@ -266,7 +266,7 @@ static int profile_tracer_perm(struct aa_profile *tracer, + if (&tracer->label == tracee) + return 0; + +- ad->label = &tracer->label; ++ ad->subj_label = &tracer->label; + ad->peer = tracee; + ad->request = 0; + ad->error = aa_capable(&tracer->label, CAP_SYS_PTRACE, +-- +2.42.0 + diff --git a/queue-6.6/bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch b/queue-6.6/bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch new file mode 100644 index 00000000000..61b7669b72d --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch @@ -0,0 +1,75 @@ +From c093b26521e8af0928c5d725c505409e1920066d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 12 Oct 2023 19:21:17 +0800 +Subject: Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE + +From: Guan Wentao + +[ Upstream commit da06ff1f585ea784c79f80e7fab0e0c4ebb49c1c ] + +Add PID/VID 0bda:b85b for Realtek RTL8852BE USB bluetooth part. +The PID/VID was reported by the patch last year. [1] +Some SBCs like rockpi 5B A8 module contains the device. +And it`s founded in website. [2] [3] + +Here is the device tables in /sys/kernel/debug/usb/devices . + +T: Bus=07 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=0bda ProdID=b85b Rev= 0.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Link: https://lore.kernel.org/all/20220420052402.19049-1-tangmeng@uniontech.com/ [1] +Link: https://forum.radxa.com/t/bluetooth-on-ubuntu/13051/4 [2] +Link: https://ubuntuforums.org/showthread.php?t=2489527 [3] + +Cc: stable@vger.kernel.org +Signed-off-by: Meng Tang +Signed-off-by: Guan Wentao +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index e3f11ea2a9fcd..66080fae072f2 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -543,6 +543,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x0bda, 0xb85b), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK | +-- +2.42.0 + diff --git a/queue-6.6/bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch b/queue-6.6/bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch new file mode 100644 index 00000000000..c5f67d73ff2 --- /dev/null +++ b/queue-6.6/bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch @@ -0,0 +1,68 @@ +From 83cbff78bef8ab61bad6f1513462e5338b832b14 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 24 Sep 2023 16:46:55 +0530 +Subject: Bluetooth: btusb: Add RTW8852BE device 13d3:3570 to device tables + +From: Masum Reza + +[ Upstream commit 02be109d3a405dbc4d53fb4b4473d7a113548088 ] + +This device is used in TP-Link TX20E WiFi+Bluetooth adapter. + +Relevant information in /sys/kernel/debug/usb/devices +about the Bluetooth device is listed as the below. + +T: Bus=01 Lev=01 Prnt=01 Port=08 Cnt=01 Dev#= 2 Spd=12 MxCh= 0 +D: Ver= 1.00 Cls=e0(wlcon) Sub=01 Prot=01 MxPS=64 #Cfgs= 1 +P: Vendor=13d3 ProdID=3570 Rev= 0.00 +S: Manufacturer=Realtek +S: Product=Bluetooth Radio +S: SerialNumber=00e04c000001 +C:* #Ifs= 2 Cfg#= 1 Atr=e0 MxPwr=500mA +I:* If#= 0 Alt= 0 #EPs= 3 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=81(I) Atr=03(Int.) MxPS= 16 Ivl=1ms +E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms +E: Ad=82(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms +I:* If#= 1 Alt= 0 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 0 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 0 Ivl=1ms +I: If#= 1 Alt= 1 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 9 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 9 Ivl=1ms +I: If#= 1 Alt= 2 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 17 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 17 Ivl=1ms +I: If#= 1 Alt= 3 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 25 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 25 Ivl=1ms +I: If#= 1 Alt= 4 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 33 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 33 Ivl=1ms +I: If#= 1 Alt= 5 #EPs= 2 Cls=e0(wlcon) Sub=01 Prot=01 Driver=btusb +E: Ad=03(O) Atr=01(Isoc) MxPS= 49 Ivl=1ms +E: Ad=83(I) Atr=01(Isoc) MxPS= 49 Ivl=1ms + +Signed-off-by: Masum Reza +Signed-off-by: Luiz Augusto von Dentz +Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE") +Signed-off-by: Sasha Levin +--- + drivers/bluetooth/btusb.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c +index 63ebd5677d267..e3f11ea2a9fcd 100644 +--- a/drivers/bluetooth/btusb.c ++++ b/drivers/bluetooth/btusb.c +@@ -543,6 +543,8 @@ static const struct usb_device_id quirks_table[] = { + BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x0bda, 0x887b), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, ++ { USB_DEVICE(0x13d3, 0x3570), .driver_info = BTUSB_REALTEK | ++ BTUSB_WIDEBAND_SPEECH }, + { USB_DEVICE(0x13d3, 0x3571), .driver_info = BTUSB_REALTEK | + BTUSB_WIDEBAND_SPEECH }, + +-- +2.42.0 + diff --git a/queue-6.6/cxl-port-fix-delete_endpoint-vs-parent-unregistratio.patch b/queue-6.6/cxl-port-fix-delete_endpoint-vs-parent-unregistratio.patch new file mode 100644 index 00000000000..af69a88662a --- /dev/null +++ b/queue-6.6/cxl-port-fix-delete_endpoint-vs-parent-unregistratio.patch @@ -0,0 +1,121 @@ +From 1fb8159e9c2490c44b8cf3061ec4b7598ed0cb7d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 27 Oct 2023 20:13:23 -0700 +Subject: cxl/port: Fix delete_endpoint() vs parent unregistration race + +From: Dan Williams + +[ Upstream commit 8d2ad999ca3c64cb08cf6a58d227b9d9e746d708 ] + +The CXL subsystem, at cxl_mem ->probe() time, establishes a lineage of +ports (struct cxl_port objects) between an endpoint and the root of a +CXL topology. Each port including the endpoint port is attached to the +cxl_port driver. + +Given that setup, it follows that when either any port in that lineage +goes through a cxl_port ->remove() event, or the memdev goes through a +cxl_mem ->remove() event. The hierarchy below the removed port, or the +entire hierarchy if the memdev is removed needs to come down. + +The delete_endpoint() callback is careful to check whether it is being +called to tear down the hierarchy, or if it is only being called to +teardown the memdev because an ancestor port is going through +->remove(). + +That care needs to take the device_lock() of the endpoint's parent. +Which requires 2 bugs to be fixed: + +1/ A reference on the parent is needed to prevent use-after-free + scenarios like this signature: + + BUG: spinlock bad magic on CPU#0, kworker/u56:0/11 + Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS edk2-20230524-3.fc38 05/24/2023 + Workqueue: cxl_port detach_memdev [cxl_core] + RIP: 0010:spin_bug+0x65/0xa0 + Call Trace: + do_raw_spin_lock+0x69/0xa0 + __mutex_lock+0x695/0xb80 + delete_endpoint+0xad/0x150 [cxl_core] + devres_release_all+0xb8/0x110 + device_unbind_cleanup+0xe/0x70 + device_release_driver_internal+0x1d2/0x210 + detach_memdev+0x15/0x20 [cxl_core] + process_one_work+0x1e3/0x4c0 + worker_thread+0x1dd/0x3d0 + +2/ In the case of RCH topologies, the parent device that needs to be + locked is not always @port->dev as returned by cxl_mem_find_port(), use + endpoint->dev.parent instead. + +Fixes: 8dd2bc0f8e02 ("cxl/mem: Add the cxl_mem driver") +Cc: +Reported-by: Robert Richter +Closes: http://lore.kernel.org/r/20231018171713.1883517-2-rrichter@amd.com +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/port.c | 34 +++++++++++++++++++--------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/drivers/cxl/core/port.c b/drivers/cxl/core/port.c +index 2c6001592fe20..6a75a3cb601ec 100644 +--- a/drivers/cxl/core/port.c ++++ b/drivers/cxl/core/port.c +@@ -1242,35 +1242,39 @@ static struct device *grandparent(struct device *dev) + return NULL; + } + ++static struct device *endpoint_host(struct cxl_port *endpoint) ++{ ++ struct cxl_port *port = to_cxl_port(endpoint->dev.parent); ++ ++ if (is_cxl_root(port)) ++ return port->uport_dev; ++ return &port->dev; ++} ++ + static void delete_endpoint(void *data) + { + struct cxl_memdev *cxlmd = data; + struct cxl_port *endpoint = cxlmd->endpoint; +- struct cxl_port *parent_port; +- struct device *parent; +- +- parent_port = cxl_mem_find_port(cxlmd, NULL); +- if (!parent_port) +- goto out; +- parent = &parent_port->dev; ++ struct device *host = endpoint_host(endpoint); + +- device_lock(parent); +- if (parent->driver && !endpoint->dead) { +- devm_release_action(parent, cxl_unlink_parent_dport, endpoint); +- devm_release_action(parent, cxl_unlink_uport, endpoint); +- devm_release_action(parent, unregister_port, endpoint); ++ device_lock(host); ++ if (host->driver && !endpoint->dead) { ++ devm_release_action(host, cxl_unlink_parent_dport, endpoint); ++ devm_release_action(host, cxl_unlink_uport, endpoint); ++ devm_release_action(host, unregister_port, endpoint); + } + cxlmd->endpoint = NULL; +- device_unlock(parent); +- put_device(parent); +-out: ++ device_unlock(host); + put_device(&endpoint->dev); ++ put_device(host); + } + + int cxl_endpoint_autoremove(struct cxl_memdev *cxlmd, struct cxl_port *endpoint) + { ++ struct device *host = endpoint_host(endpoint); + struct device *dev = &cxlmd->dev; + ++ get_device(host); + get_device(&endpoint->dev); + cxlmd->endpoint = endpoint; + cxlmd->depth = endpoint->depth; +-- +2.42.0 + diff --git a/queue-6.6/cxl-region-fix-x1-root-decoder-granularity-calculati.patch b/queue-6.6/cxl-region-fix-x1-root-decoder-granularity-calculati.patch new file mode 100644 index 00000000000..3dec3d47b5d --- /dev/null +++ b/queue-6.6/cxl-region-fix-x1-root-decoder-granularity-calculati.patch @@ -0,0 +1,93 @@ +From 81d1fc2e5b8aa62e8d1ca5524b89b8e25127f2dd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 26 Oct 2023 10:09:06 -0700 +Subject: cxl/region: Fix x1 root-decoder granularity calculations + +From: Jim Harris + +[ Upstream commit 98a04c7aced2b43b3ac4befe216c4eecc7257d4b ] + +Root decoder granularity must match value from CFWMS, which may not +be the region's granularity for non-interleaved root decoders. + +So when calculating granularities for host bridge decoders, use the +region's granularity instead of the root decoder's granularity to ensure +the correct granularities are set for the host bridge decoders and any +downstream switch decoders. + +Test configuration is 1 host bridge * 2 switches * 2 endpoints per switch. + +Region created with 2048 granularity using following command line: + +cxl create-region -m -d decoder0.0 -w 4 mem0 mem2 mem1 mem3 \ + -g 2048 -s 2048M + +Use "cxl list -PDE | grep granularity" to get a view of the granularity +set at each level of the topology. + +Before this patch: + "interleave_granularity":2048, + "interleave_granularity":2048, + "interleave_granularity":512, + "interleave_granularity":2048, + "interleave_granularity":2048, + "interleave_granularity":512, +"interleave_granularity":256, + +After: + "interleave_granularity":2048, + "interleave_granularity":2048, + "interleave_granularity":4096, + "interleave_granularity":2048, + "interleave_granularity":2048, + "interleave_granularity":4096, +"interleave_granularity":2048, + +Fixes: 27b3f8d13830 ("cxl/region: Program target lists") +Cc: +Signed-off-by: Jim Harris +Link: https://lore.kernel.org/r/169824893473.1403938.16110924262989774582.stgit@bgt-140510-bm03.eng.stellus.in +[djbw: fixup the prebuilt cxl_test region] +Signed-off-by: Dan Williams +Signed-off-by: Sasha Levin +--- + drivers/cxl/core/region.c | 9 ++++++++- + tools/testing/cxl/test/cxl.c | 2 +- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/drivers/cxl/core/region.c b/drivers/cxl/core/region.c +index 359af06233021..9d60020c5cb3b 100644 +--- a/drivers/cxl/core/region.c ++++ b/drivers/cxl/core/region.c +@@ -1127,7 +1127,14 @@ static int cxl_port_setup_targets(struct cxl_port *port, + } + + if (is_cxl_root(parent_port)) { +- parent_ig = cxlrd->cxlsd.cxld.interleave_granularity; ++ /* ++ * Root decoder IG is always set to value in CFMWS which ++ * may be different than this region's IG. We can use the ++ * region's IG here since interleave_granularity_store() ++ * does not allow interleaved host-bridges with ++ * root IG != region IG. ++ */ ++ parent_ig = p->interleave_granularity; + parent_iw = cxlrd->cxlsd.cxld.interleave_ways; + /* + * For purposes of address bit routing, use power-of-2 math for +diff --git a/tools/testing/cxl/test/cxl.c b/tools/testing/cxl/test/cxl.c +index fb6ab9cef84f7..b885462999022 100644 +--- a/tools/testing/cxl/test/cxl.c ++++ b/tools/testing/cxl/test/cxl.c +@@ -831,7 +831,7 @@ static void mock_init_hdm_decoder(struct cxl_decoder *cxld) + cxld->interleave_ways = 2; + else + cxld->interleave_ways = 1; +- cxld->interleave_granularity = 256; ++ cxld->interleave_granularity = 4096; + cxld->hpa_range = (struct range) { + .start = base, + .end = base + size - 1, +-- +2.42.0 + diff --git a/queue-6.6/drm-amd-display-enable-dsc_clk-even-if-dsc_pg-disabl.patch b/queue-6.6/drm-amd-display-enable-dsc_clk-even-if-dsc_pg-disabl.patch new file mode 100644 index 00000000000..7db39a03209 --- /dev/null +++ b/queue-6.6/drm-amd-display-enable-dsc_clk-even-if-dsc_pg-disabl.patch @@ -0,0 +1,83 @@ +From fb508286dd45a6c20533ea1da620dc625fca6b47 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 18 Sep 2023 16:52:54 -0400 +Subject: drm/amd/display: enable dsc_clk even if dsc_pg disabled + +From: Muhammad Ahmed + +[ Upstream commit 40255df370e94d44f0f0a924400d68db0ee31bec ] + +[why] +need to enable dsc_clk regardless dsc_pg + +Reviewed-by: Charlene Liu +Cc: Mario Limonciello +Cc: Alex Deucher +Cc: stable@vger.kernel.org +Acked-by: Aurabindo Pillai +Signed-off-by: Muhammad Ahmed +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/core/dc.c | 8 ++++---- + drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c | 3 +++ + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c +index 38abbd0c9d997..186936ad283a5 100644 +--- a/drivers/gpu/drm/amd/display/dc/core/dc.c ++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c +@@ -1843,7 +1843,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + if (dc->hwss.subvp_pipe_control_lock) + dc->hwss.subvp_pipe_control_lock(dc, context, true, true, NULL, subvp_prev_use); + +- if (dc->debug.enable_double_buffered_dsc_pg_support) ++ if (dc->hwss.update_dsc_pg) + dc->hwss.update_dsc_pg(dc, context, false); + + disable_dangling_plane(dc, context); +@@ -1950,7 +1950,7 @@ static enum dc_status dc_commit_state_no_check(struct dc *dc, struct dc_state *c + dc->hwss.optimize_bandwidth(dc, context); + } + +- if (dc->debug.enable_double_buffered_dsc_pg_support) ++ if (dc->hwss.update_dsc_pg) + dc->hwss.update_dsc_pg(dc, context, true); + + if (dc->ctx->dce_version >= DCE_VERSION_MAX) +@@ -2197,7 +2197,7 @@ void dc_post_update_surfaces_to_stream(struct dc *dc) + + dc->hwss.optimize_bandwidth(dc, context); + +- if (dc->debug.enable_double_buffered_dsc_pg_support) ++ if (dc->hwss.update_dsc_pg) + dc->hwss.update_dsc_pg(dc, context, true); + } + +@@ -3533,7 +3533,7 @@ static void commit_planes_for_stream(struct dc *dc, + if (get_seamless_boot_stream_count(context) == 0) + dc->hwss.prepare_bandwidth(dc, context); + +- if (dc->debug.enable_double_buffered_dsc_pg_support) ++ if (dc->hwss.update_dsc_pg) + dc->hwss.update_dsc_pg(dc, context, false); + + context_clock_trace(dc, context); +diff --git a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +index be59e1c02f8aa..c9140b50c3454 100644 +--- a/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/dcn32/dcn32_hwseq.c +@@ -77,6 +77,9 @@ void dcn32_dsc_pg_control( + if (hws->ctx->dc->debug.disable_dsc_power_gate) + return; + ++ if (!hws->ctx->dc->debug.enable_double_buffered_dsc_pg_support) ++ return; ++ + REG_GET(DC_IP_REQUEST_CNTL, IP_REQUEST_EN, &org_ip_request_cntl); + if (org_ip_request_cntl == 0) + REG_SET(DC_IP_REQUEST_CNTL, 0, IP_REQUEST_EN, 1); +-- +2.42.0 + diff --git a/queue-6.6/rcutorture-fix-stuttering-races-and-other-issues.patch b/queue-6.6/rcutorture-fix-stuttering-races-and-other-issues.patch new file mode 100644 index 00000000000..828d20ea051 --- /dev/null +++ b/queue-6.6/rcutorture-fix-stuttering-races-and-other-issues.patch @@ -0,0 +1,127 @@ +From 6b13da968c234929a21e3dc1e7120e617481ad86 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 29 Jul 2023 14:27:31 +0000 +Subject: rcutorture: Fix stuttering races and other issues + +From: Joel Fernandes (Google) + +[ Upstream commit cca42bd8eb1b54a4c9bbf48c79d120e66619a3e4 ] + +The stuttering code isn't functioning as expected. Ideally, it should +pause the torture threads for a designated period before resuming. Yet, +it fails to halt the test for the correct duration. Additionally, a race +condition exists, potentially causing the stuttering code to pause for +an extended period if the 'spt' variable is non-zero due to the stutter +orchestration thread's inadequate CPU time. + +Moreover, over-stuttering can hinder RCU's progress on TREE07 kernels. +This happens as the stuttering code may run within a softirq due to RCU +callbacks. Consequently, ksoftirqd keeps a CPU busy for several seconds, +thus obstructing RCU's progress. This situation triggers a warning +message in the logs: + +[ 2169.481783] rcu_torture_writer: rtort_pipe_count: 9 + +This warning suggests that an RCU torture object, although invisible to +RCU readers, couldn't make it past the pipe array and be freed -- a +strong indication that there weren't enough grace periods during the +stutter interval. + +To address these issues, this patch sets the "stutter end" time to an +absolute point in the future set by the main stutter thread. This is +then used for waiting in stutter_wait(). While the stutter thread still +defines this absolute time, the waiters' waiting logic doesn't rely on +the stutter thread receiving sufficient CPU time to halt the stuttering +as the halting is now self-controlled. + +Cc: stable@vger.kernel.org +Signed-off-by: Joel Fernandes (Google) +Signed-off-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Signed-off-by: Sasha Levin +--- + kernel/torture.c | 45 ++++++++++++--------------------------------- + 1 file changed, 12 insertions(+), 33 deletions(-) + +diff --git a/kernel/torture.c b/kernel/torture.c +index e851b8e9390b3..c7b475883b9a8 100644 +--- a/kernel/torture.c ++++ b/kernel/torture.c +@@ -721,7 +721,7 @@ static void torture_shutdown_cleanup(void) + * suddenly applied to or removed from the system. + */ + static struct task_struct *stutter_task; +-static int stutter_pause_test; ++static ktime_t stutter_till_abs_time; + static int stutter; + static int stutter_gap; + +@@ -731,30 +731,16 @@ static int stutter_gap; + */ + bool stutter_wait(const char *title) + { +- unsigned int i = 0; + bool ret = false; +- int spt; ++ ktime_t till_ns; + + cond_resched_tasks_rcu_qs(); +- spt = READ_ONCE(stutter_pause_test); +- for (; spt; spt = READ_ONCE(stutter_pause_test)) { +- if (!ret && !rt_task(current)) { +- sched_set_normal(current, MAX_NICE); +- ret = true; +- } +- if (spt == 1) { +- torture_hrtimeout_jiffies(1, NULL); +- } else if (spt == 2) { +- while (READ_ONCE(stutter_pause_test)) { +- if (!(i++ & 0xffff)) +- torture_hrtimeout_us(10, 0, NULL); +- cond_resched(); +- } +- } else { +- torture_hrtimeout_jiffies(round_jiffies_relative(HZ), NULL); +- } +- torture_shutdown_absorb(title); ++ till_ns = READ_ONCE(stutter_till_abs_time); ++ if (till_ns && ktime_before(ktime_get(), till_ns)) { ++ torture_hrtimeout_ns(till_ns, 0, HRTIMER_MODE_ABS, NULL); ++ ret = true; + } ++ torture_shutdown_absorb(title); + return ret; + } + EXPORT_SYMBOL_GPL(stutter_wait); +@@ -765,23 +751,16 @@ EXPORT_SYMBOL_GPL(stutter_wait); + */ + static int torture_stutter(void *arg) + { +- DEFINE_TORTURE_RANDOM(rand); +- int wtime; ++ ktime_t till_ns; + + VERBOSE_TOROUT_STRING("torture_stutter task started"); + do { + if (!torture_must_stop() && stutter > 1) { +- wtime = stutter; +- if (stutter > 2) { +- WRITE_ONCE(stutter_pause_test, 1); +- wtime = stutter - 3; +- torture_hrtimeout_jiffies(wtime, &rand); +- wtime = 2; +- } +- WRITE_ONCE(stutter_pause_test, 2); +- torture_hrtimeout_jiffies(wtime, NULL); ++ till_ns = ktime_add_ns(ktime_get(), ++ jiffies_to_nsecs(stutter)); ++ WRITE_ONCE(stutter_till_abs_time, till_ns); ++ torture_hrtimeout_jiffies(stutter - 1, NULL); + } +- WRITE_ONCE(stutter_pause_test, 0); + if (!torture_must_stop()) + torture_hrtimeout_jiffies(stutter_gap, NULL); + torture_shutdown_absorb("torture_stutter"); +-- +2.42.0 + diff --git a/queue-6.6/selftests-resctrl-extend-signal-handler-coverage-to-.patch b/queue-6.6/selftests-resctrl-extend-signal-handler-coverage-to-.patch new file mode 100644 index 00000000000..4e78af54676 --- /dev/null +++ b/queue-6.6/selftests-resctrl-extend-signal-handler-coverage-to-.patch @@ -0,0 +1,320 @@ +From c57c67ed524ea6affabaeeeb4aee3e7d60b9386b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 2 Oct 2023 12:48:08 +0300 +Subject: selftests/resctrl: Extend signal handler coverage to unmount on + receiving signal +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 3aff5146445582454c35900f3c0c972987cdd595 ] + +Unmounting resctrl FS has been moved into the per test functions in +resctrl_tests.c by commit caddc0fbe495 ("selftests/resctrl: Move +resctrl FS mount/umount to higher level"). In case a signal (SIGINT, +SIGTERM, or SIGHUP) is received, the running selftest is aborted by +ctrlc_handler() which then unmounts resctrl fs before exiting. The +current section between signal_handler_register() and +signal_handler_unregister(), however, does not cover the entire +duration when resctrl FS is mounted. + +Move signal_handler_register() and signal_handler_unregister() calls +from per test files into resctrl_tests.c to properly unmount resctrl +fs. In order to not add signal_handler_register()/unregister() n times, +create helpers test_prepare() and test_cleanup(). + +Do not call ksft_exit_fail_msg() in test_prepare() but only in the per +test function to keep the control flow cleaner without adding calls to +exit() deep into the call chain. + +Adjust child process kill() call in ctrlc_handler() to only be invoked +if the child was already forked. + +Fixes: caddc0fbe495 ("selftests/resctrl: Move resctrl FS mount/umount to higher level") +Signed-off-by: Ilpo Järvinen +Tested-by: Shaopeng Tan +Reviewed-by: Shaopeng Tan +Reviewed-by: Reinette Chatre +Cc: +Signed-off-by: Shuah Khan +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/resctrl/cat_test.c | 8 --- + .../testing/selftests/resctrl/resctrl_tests.c | 69 ++++++++++++------- + tools/testing/selftests/resctrl/resctrl_val.c | 22 +++--- + 3 files changed, 55 insertions(+), 44 deletions(-) + +diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c +index 97b87285ab2a9..224ba8544d8af 100644 +--- a/tools/testing/selftests/resctrl/cat_test.c ++++ b/tools/testing/selftests/resctrl/cat_test.c +@@ -167,12 +167,6 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + strcpy(param.filename, RESULT_FILE_NAME1); + param.num_of_runs = 0; + param.cpu_no = sibling_cpu_no; +- } else { +- ret = signal_handler_register(); +- if (ret) { +- kill(bm_pid, SIGKILL); +- goto out; +- } + } + + remove(param.filename); +@@ -209,10 +203,8 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + } + close(pipefd[0]); + kill(bm_pid, SIGKILL); +- signal_handler_unregister(); + } + +-out: + cat_test_cleanup(); + + return ret; +diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c +index 1ac22c6d8ce8f..31373b69e675d 100644 +--- a/tools/testing/selftests/resctrl/resctrl_tests.c ++++ b/tools/testing/selftests/resctrl/resctrl_tests.c +@@ -67,15 +67,39 @@ void tests_cleanup(void) + cat_test_cleanup(); + } + +-static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no) ++static int test_prepare(void) + { + int res; + +- ksft_print_msg("Starting MBM BW change ...\n"); ++ res = signal_handler_register(); ++ if (res) { ++ ksft_print_msg("Failed to register signal handler\n"); ++ return res; ++ } + + res = mount_resctrlfs(); + if (res) { +- ksft_exit_fail_msg("Failed to mount resctrl FS\n"); ++ signal_handler_unregister(); ++ ksft_print_msg("Failed to mount resctrl FS\n"); ++ return res; ++ } ++ return 0; ++} ++ ++static void test_cleanup(void) ++{ ++ umount_resctrlfs(); ++ signal_handler_unregister(); ++} ++ ++static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no) ++{ ++ int res; ++ ++ ksft_print_msg("Starting MBM BW change ...\n"); ++ ++ if (test_prepare()) { ++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n"); + return; + } + +@@ -83,7 +107,7 @@ static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no) + !validate_resctrl_feature_request("L3_MON", "mbm_local_bytes") || + (get_vendor() != ARCH_INTEL)) { + ksft_test_result_skip("Hardware does not support MBM or MBM is disabled\n"); +- goto umount; ++ goto cleanup; + } + + res = mbm_bw_change(cpu_no, benchmark_cmd); +@@ -91,8 +115,8 @@ static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no) + if ((get_vendor() == ARCH_INTEL) && res) + ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n"); + +-umount: +- umount_resctrlfs(); ++cleanup: ++ test_cleanup(); + } + + static void run_mba_test(const char * const *benchmark_cmd, int cpu_no) +@@ -101,9 +125,8 @@ static void run_mba_test(const char * const *benchmark_cmd, int cpu_no) + + ksft_print_msg("Starting MBA Schemata change ...\n"); + +- res = mount_resctrlfs(); +- if (res) { +- ksft_exit_fail_msg("Failed to mount resctrl FS\n"); ++ if (test_prepare()) { ++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n"); + return; + } + +@@ -111,14 +134,14 @@ static void run_mba_test(const char * const *benchmark_cmd, int cpu_no) + !validate_resctrl_feature_request("L3_MON", "mbm_local_bytes") || + (get_vendor() != ARCH_INTEL)) { + ksft_test_result_skip("Hardware does not support MBA or MBA is disabled\n"); +- goto umount; ++ goto cleanup; + } + + res = mba_schemata_change(cpu_no, benchmark_cmd); + ksft_test_result(!res, "MBA: schemata change\n"); + +-umount: +- umount_resctrlfs(); ++cleanup: ++ test_cleanup(); + } + + static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no) +@@ -127,16 +150,15 @@ static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no) + + ksft_print_msg("Starting CMT test ...\n"); + +- res = mount_resctrlfs(); +- if (res) { +- ksft_exit_fail_msg("Failed to mount resctrl FS\n"); ++ if (test_prepare()) { ++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n"); + return; + } + + if (!validate_resctrl_feature_request("L3_MON", "llc_occupancy") || + !validate_resctrl_feature_request("L3", NULL)) { + ksft_test_result_skip("Hardware does not support CMT or CMT is disabled\n"); +- goto umount; ++ goto cleanup; + } + + res = cmt_resctrl_val(cpu_no, 5, benchmark_cmd); +@@ -144,8 +166,8 @@ static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no) + if ((get_vendor() == ARCH_INTEL) && res) + ksft_print_msg("Intel CMT may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n"); + +-umount: +- umount_resctrlfs(); ++cleanup: ++ test_cleanup(); + } + + static void run_cat_test(int cpu_no, int no_of_bits) +@@ -154,22 +176,21 @@ static void run_cat_test(int cpu_no, int no_of_bits) + + ksft_print_msg("Starting CAT test ...\n"); + +- res = mount_resctrlfs(); +- if (res) { +- ksft_exit_fail_msg("Failed to mount resctrl FS\n"); ++ if (test_prepare()) { ++ ksft_exit_fail_msg("Abnormal failure when preparing for the test\n"); + return; + } + + if (!validate_resctrl_feature_request("L3", NULL)) { + ksft_test_result_skip("Hardware does not support CAT or CAT is disabled\n"); +- goto umount; ++ goto cleanup; + } + + res = cat_perf_miss_val(cpu_no, no_of_bits, "L3"); + ksft_test_result(!res, "CAT: test\n"); + +-umount: +- umount_resctrlfs(); ++cleanup: ++ test_cleanup(); + } + + int main(int argc, char **argv) +diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c +index 01bbe11a89834..b8ca6fa40b3bf 100644 +--- a/tools/testing/selftests/resctrl/resctrl_val.c ++++ b/tools/testing/selftests/resctrl/resctrl_val.c +@@ -468,7 +468,9 @@ pid_t bm_pid, ppid; + + void ctrlc_handler(int signum, siginfo_t *info, void *ptr) + { +- kill(bm_pid, SIGKILL); ++ /* Only kill child after bm_pid is set after fork() */ ++ if (bm_pid) ++ kill(bm_pid, SIGKILL); + umount_resctrlfs(); + tests_cleanup(); + ksft_print_msg("Ending\n\n"); +@@ -485,6 +487,8 @@ int signal_handler_register(void) + struct sigaction sigact = {}; + int ret = 0; + ++ bm_pid = 0; ++ + sigact.sa_sigaction = ctrlc_handler; + sigemptyset(&sigact.sa_mask); + sigact.sa_flags = SA_SIGINFO; +@@ -706,10 +710,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + + ksft_print_msg("Benchmark PID: %d\n", bm_pid); + +- ret = signal_handler_register(); +- if (ret) +- goto out; +- + /* + * The cast removes constness but nothing mutates benchmark_cmd within + * the context of this process. At the receiving process, it becomes +@@ -721,19 +721,19 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + /* Taskset benchmark to specified cpu */ + ret = taskset_benchmark(bm_pid, param->cpu_no); + if (ret) +- goto unregister; ++ goto out; + + /* Write benchmark to specified control&monitoring grp in resctrl FS */ + ret = write_bm_pid_to_resctrl(bm_pid, param->ctrlgrp, param->mongrp, + resctrl_val); + if (ret) +- goto unregister; ++ goto out; + + if (!strncmp(resctrl_val, MBM_STR, sizeof(MBM_STR)) || + !strncmp(resctrl_val, MBA_STR, sizeof(MBA_STR))) { + ret = initialize_mem_bw_imc(); + if (ret) +- goto unregister; ++ goto out; + + initialize_mem_bw_resctrl(param->ctrlgrp, param->mongrp, + param->cpu_no, resctrl_val); +@@ -748,7 +748,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + sizeof(pipe_message)) { + perror("# failed reading message from child process"); + close(pipefd[0]); +- goto unregister; ++ goto out; + } + } + close(pipefd[0]); +@@ -757,7 +757,7 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + if (sigqueue(bm_pid, SIGUSR1, value) == -1) { + perror("# sigqueue SIGUSR1 to child"); + ret = errno; +- goto unregister; ++ goto out; + } + + /* Give benchmark enough time to fully run */ +@@ -786,8 +786,6 @@ int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *par + } + } + +-unregister: +- signal_handler_unregister(); + out: + kill(bm_pid, SIGKILL); + +-- +2.42.0 + diff --git a/queue-6.6/selftests-resctrl-make-benchmark-command-const-and-b.patch b/queue-6.6/selftests-resctrl-make-benchmark-command-const-and-b.patch new file mode 100644 index 00000000000..ee87d605573 --- /dev/null +++ b/queue-6.6/selftests-resctrl-make-benchmark-command-const-and-b.patch @@ -0,0 +1,293 @@ +From 06be35495ce0e4f598017fc4324198595deed4bd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 12:53:37 +0300 +Subject: selftests/resctrl: Make benchmark command const and build it with + pointers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit e33cb5702a9f287d829b0e9e6abe57f6a4aba6d2 ] + +Benchmark command is used in multiple tests so it should not be +mutated by the tests but CMT test alters span argument. Due to the +order of tests (CMT test runs last), mutating the span argument in CMT +test does not trigger any real problems currently. + +Mark benchmark_cmd strings as const and setup the benchmark command +using pointers. Because the benchmark command becomes const, the input +arguments can be used directly. Besides being simpler, using the input +arguments directly also removes the internal size restriction. + +CMT test has to create a copy of the benchmark command before altering +the benchmark command. + +Signed-off-by: Ilpo Järvinen +Tested-by: Shaopeng Tan +Reviewed-by: Shaopeng Tan +Reviewed-by: Reinette Chatre +Reviewed-by: "Wieczor-Retman, Maciej" +Signed-off-by: Shuah Khan +Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/resctrl/cmt_test.c | 25 +++++++++--- + tools/testing/selftests/resctrl/mba_test.c | 2 +- + tools/testing/selftests/resctrl/mbm_test.c | 2 +- + tools/testing/selftests/resctrl/resctrl.h | 10 +++-- + .../testing/selftests/resctrl/resctrl_tests.c | 39 ++++++++----------- + tools/testing/selftests/resctrl/resctrl_val.c | 10 ++++- + 6 files changed, 53 insertions(+), 35 deletions(-) + +diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c +index 33dbe51e77122..50bdbce9fba95 100644 +--- a/tools/testing/selftests/resctrl/cmt_test.c ++++ b/tools/testing/selftests/resctrl/cmt_test.c +@@ -68,14 +68,17 @@ void cmt_test_cleanup(void) + remove(RESULT_FILE_NAME); + } + +-int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) ++int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd) + { ++ const char * const *cmd = benchmark_cmd; ++ const char *new_cmd[BENCHMARK_ARGS]; + unsigned long cache_size = 0; + unsigned long long_mask; ++ char *span_str = NULL; + char cbm_mask[256]; + int count_of_bits; + size_t span; +- int ret; ++ int ret, i; + + ret = get_cbm_mask("L3", cbm_mask); + if (ret) +@@ -108,12 +111,23 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) + }; + + span = cache_size * n / count_of_bits; +- if (strcmp(benchmark_cmd[0], "fill_buf") == 0) +- sprintf(benchmark_cmd[1], "%zu", span); ++ ++ if (strcmp(cmd[0], "fill_buf") == 0) { ++ /* Duplicate the command to be able to replace span in it */ ++ for (i = 0; benchmark_cmd[i]; i++) ++ new_cmd[i] = benchmark_cmd[i]; ++ new_cmd[i] = NULL; ++ ++ ret = asprintf(&span_str, "%zu", span); ++ if (ret < 0) ++ return -1; ++ new_cmd[1] = span_str; ++ cmd = new_cmd; ++ } + + remove(RESULT_FILE_NAME); + +- ret = resctrl_val(benchmark_cmd, ¶m); ++ ret = resctrl_val(cmd, ¶m); + if (ret) + goto out; + +@@ -121,6 +135,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) + + out: + cmt_test_cleanup(); ++ free(span_str); + + return ret; + } +diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c +index c5c0588779d2b..d3bf4368341ec 100644 +--- a/tools/testing/selftests/resctrl/mba_test.c ++++ b/tools/testing/selftests/resctrl/mba_test.c +@@ -141,7 +141,7 @@ void mba_test_cleanup(void) + remove(RESULT_FILE_NAME); + } + +-int mba_schemata_change(int cpu_no, char **benchmark_cmd) ++int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd) + { + struct resctrl_val_param param = { + .resctrl_val = MBA_STR, +diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c +index 445aea1c64e83..d3c0d30c676a7 100644 +--- a/tools/testing/selftests/resctrl/mbm_test.c ++++ b/tools/testing/selftests/resctrl/mbm_test.c +@@ -109,7 +109,7 @@ void mbm_test_cleanup(void) + remove(RESULT_FILE_NAME); + } + +-int mbm_bw_change(int cpu_no, char **benchmark_cmd) ++int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd) + { + struct resctrl_val_param param = { + .resctrl_val = MBM_STR, +diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h +index d33452fde5b94..8578a8b4e1459 100644 +--- a/tools/testing/selftests/resctrl/resctrl.h ++++ b/tools/testing/selftests/resctrl/resctrl.h +@@ -33,6 +33,8 @@ + + #define END_OF_TESTS 1 + ++#define BENCHMARK_ARGS 64 ++ + #define DEFAULT_SPAN (250 * MB) + + #define PARENT_EXIT(err_msg) \ +@@ -92,11 +94,11 @@ int write_bm_pid_to_resctrl(pid_t bm_pid, char *ctrlgrp, char *mongrp, + int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, + int group_fd, unsigned long flags); + int run_fill_buf(size_t span, int memflush, int op, bool once); +-int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param); +-int mbm_bw_change(int cpu_no, char **benchmark_cmd); ++int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param); ++int mbm_bw_change(int cpu_no, const char * const *benchmark_cmd); + void tests_cleanup(void); + void mbm_test_cleanup(void); +-int mba_schemata_change(int cpu_no, char **benchmark_cmd); ++int mba_schemata_change(int cpu_no, const char * const *benchmark_cmd); + void mba_test_cleanup(void); + int get_cbm_mask(char *cache_type, char *cbm_mask); + int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size); +@@ -106,7 +108,7 @@ void signal_handler_unregister(void); + int cat_val(struct resctrl_val_param *param, size_t span); + void cat_test_cleanup(void); + int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type); +-int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd); ++int cmt_resctrl_val(int cpu_no, int n, const char * const *benchmark_cmd); + unsigned int count_bits(unsigned long n); + void cmt_test_cleanup(void); + int get_core_sibling(int cpu_no); +diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c +index 1826b674ea300..1ac22c6d8ce8f 100644 +--- a/tools/testing/selftests/resctrl/resctrl_tests.c ++++ b/tools/testing/selftests/resctrl/resctrl_tests.c +@@ -10,9 +10,6 @@ + */ + #include "resctrl.h" + +-#define BENCHMARK_ARGS 64 +-#define BENCHMARK_ARG_SIZE 64 +- + static int detect_vendor(void) + { + FILE *inf = fopen("/proc/cpuinfo", "r"); +@@ -70,7 +67,7 @@ void tests_cleanup(void) + cat_test_cleanup(); + } + +-static void run_mbm_test(char **benchmark_cmd, int cpu_no) ++static void run_mbm_test(const char * const *benchmark_cmd, int cpu_no) + { + int res; + +@@ -98,7 +95,7 @@ static void run_mbm_test(char **benchmark_cmd, int cpu_no) + umount_resctrlfs(); + } + +-static void run_mba_test(char **benchmark_cmd, int cpu_no) ++static void run_mba_test(const char * const *benchmark_cmd, int cpu_no) + { + int res; + +@@ -124,7 +121,7 @@ static void run_mba_test(char **benchmark_cmd, int cpu_no) + umount_resctrlfs(); + } + +-static void run_cmt_test(char **benchmark_cmd, int cpu_no) ++static void run_cmt_test(const char * const *benchmark_cmd, int cpu_no) + { + int res; + +@@ -178,11 +175,12 @@ static void run_cat_test(int cpu_no, int no_of_bits) + int main(int argc, char **argv) + { + bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true; +- char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE]; + int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0; +- char *benchmark_cmd[BENCHMARK_ARGS]; ++ const char *benchmark_cmd[BENCHMARK_ARGS]; + int ben_ind, ben_count, tests = 0; ++ char *span_str = NULL; + bool cat_test = true; ++ int ret; + + for (i = 0; i < argc; i++) { + if (strcmp(argv[i], "-b") == 0) { +@@ -262,23 +260,19 @@ int main(int argc, char **argv) + ksft_exit_fail_msg("Too long benchmark command.\n"); + + /* Extract benchmark command from command line. */ +- for (i = ben_ind; i < argc; i++) { +- benchmark_cmd[i - ben_ind] = benchmark_cmd_area[i]; +- if (strlen(argv[i]) >= BENCHMARK_ARG_SIZE) +- ksft_exit_fail_msg("Too long benchmark command argument.\n"); +- sprintf(benchmark_cmd[i - ben_ind], "%s", argv[i]); +- } ++ for (i = 0; i < argc - ben_ind; i++) ++ benchmark_cmd[i] = argv[i + ben_ind]; + benchmark_cmd[ben_count] = NULL; + } else { + /* If no benchmark is given by "-b" argument, use fill_buf. */ +- for (i = 0; i < 5; i++) +- benchmark_cmd[i] = benchmark_cmd_area[i]; +- +- strcpy(benchmark_cmd[0], "fill_buf"); +- sprintf(benchmark_cmd[1], "%u", DEFAULT_SPAN); +- strcpy(benchmark_cmd[2], "1"); +- strcpy(benchmark_cmd[3], "0"); +- strcpy(benchmark_cmd[4], "false"); ++ benchmark_cmd[0] = "fill_buf"; ++ ret = asprintf(&span_str, "%u", DEFAULT_SPAN); ++ if (ret < 0) ++ ksft_exit_fail_msg("Out of memory!\n"); ++ benchmark_cmd[1] = span_str; ++ benchmark_cmd[2] = "1"; ++ benchmark_cmd[3] = "0"; ++ benchmark_cmd[4] = "false"; + benchmark_cmd[5] = NULL; + } + +@@ -304,5 +298,6 @@ int main(int argc, char **argv) + if (cat_test) + run_cat_test(cpu_no, no_of_bits); + ++ free(span_str); + ksft_finished(); + } +diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c +index ee07e0943f583..01bbe11a89834 100644 +--- a/tools/testing/selftests/resctrl/resctrl_val.c ++++ b/tools/testing/selftests/resctrl/resctrl_val.c +@@ -629,7 +629,7 @@ measure_vals(struct resctrl_val_param *param, unsigned long *bw_resc_start) + * + * Return: 0 on success. non-zero on failure. + */ +-int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) ++int resctrl_val(const char * const *benchmark_cmd, struct resctrl_val_param *param) + { + char *resctrl_val = param->resctrl_val; + unsigned long bw_resc_start = 0; +@@ -710,7 +710,13 @@ int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param) + if (ret) + goto out; + +- value.sival_ptr = benchmark_cmd; ++ /* ++ * The cast removes constness but nothing mutates benchmark_cmd within ++ * the context of this process. At the receiving process, it becomes ++ * argv, which is mutable, on exec() but that's after fork() so it ++ * doesn't matter for the process running the tests. ++ */ ++ value.sival_ptr = (void *)benchmark_cmd; + + /* Taskset benchmark to specified cpu */ + ret = taskset_benchmark(bm_pid, param->cpu_no); +-- +2.42.0 + diff --git a/queue-6.6/selftests-resctrl-remove-bw_report-and-bm_type-from-.patch b/queue-6.6/selftests-resctrl-remove-bw_report-and-bm_type-from-.patch new file mode 100644 index 00000000000..237934588aa --- /dev/null +++ b/queue-6.6/selftests-resctrl-remove-bw_report-and-bm_type-from-.patch @@ -0,0 +1,171 @@ +From 9d927dab1a26936dae56d5e161f55f57358b70a2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 12:53:34 +0300 +Subject: selftests/resctrl: Remove bw_report and bm_type from main() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit 47e36f16c7846bf3627ff68525e02555c53dc99e ] + +bw_report is always set to "reads" and bm_type is set to "fill_buf" but +is never used. + +Set bw_report directly to "reads" in MBA/MBM test and remove bm_type. + +Signed-off-by: Ilpo Järvinen +Tested-by: Shaopeng Tan +Reviewed-by: Reinette Chatre +Reviewed-by: Shaopeng Tan +Reviewed-by: "Wieczor-Retman, Maciej" +Signed-off-by: Shuah Khan +Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/resctrl/mba_test.c | 4 ++-- + tools/testing/selftests/resctrl/mbm_test.c | 4 ++-- + tools/testing/selftests/resctrl/resctrl.h | 4 ++-- + .../testing/selftests/resctrl/resctrl_tests.c | 18 +++++++----------- + 4 files changed, 13 insertions(+), 17 deletions(-) + +diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c +index c7d1ec6d81ea8..c5c0588779d2b 100644 +--- a/tools/testing/selftests/resctrl/mba_test.c ++++ b/tools/testing/selftests/resctrl/mba_test.c +@@ -141,7 +141,7 @@ void mba_test_cleanup(void) + remove(RESULT_FILE_NAME); + } + +-int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd) ++int mba_schemata_change(int cpu_no, char **benchmark_cmd) + { + struct resctrl_val_param param = { + .resctrl_val = MBA_STR, +@@ -149,7 +149,7 @@ int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd) + .mongrp = "m1", + .cpu_no = cpu_no, + .filename = RESULT_FILE_NAME, +- .bw_report = bw_report, ++ .bw_report = "reads", + .setup = mba_setup + }; + int ret; +diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c +index d0c26a5e89fb9..724412186d636 100644 +--- a/tools/testing/selftests/resctrl/mbm_test.c ++++ b/tools/testing/selftests/resctrl/mbm_test.c +@@ -109,7 +109,7 @@ void mbm_test_cleanup(void) + remove(RESULT_FILE_NAME); + } + +-int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd) ++int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd) + { + struct resctrl_val_param param = { + .resctrl_val = MBM_STR, +@@ -118,7 +118,7 @@ int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd + .span = span, + .cpu_no = cpu_no, + .filename = RESULT_FILE_NAME, +- .bw_report = bw_report, ++ .bw_report = "reads", + .setup = mbm_setup + }; + int ret; +diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h +index 9e46fa90e7be7..df75c89060329 100644 +--- a/tools/testing/selftests/resctrl/resctrl.h ++++ b/tools/testing/selftests/resctrl/resctrl.h +@@ -93,10 +93,10 @@ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, + int group_fd, unsigned long flags); + int run_fill_buf(size_t span, int memflush, int op, bool once); + int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param); +-int mbm_bw_change(size_t span, int cpu_no, char *bw_report, char **benchmark_cmd); ++int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd); + void tests_cleanup(void); + void mbm_test_cleanup(void); +-int mba_schemata_change(int cpu_no, char *bw_report, char **benchmark_cmd); ++int mba_schemata_change(int cpu_no, char **benchmark_cmd); + void mba_test_cleanup(void); + int get_cbm_mask(char *cache_type, char *cbm_mask); + int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size); +diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c +index 59a361660d8c8..116f67d833f75 100644 +--- a/tools/testing/selftests/resctrl/resctrl_tests.c ++++ b/tools/testing/selftests/resctrl/resctrl_tests.c +@@ -70,8 +70,7 @@ void tests_cleanup(void) + cat_test_cleanup(); + } + +-static void run_mbm_test(char **benchmark_cmd, size_t span, +- int cpu_no, char *bw_report) ++static void run_mbm_test(char **benchmark_cmd, size_t span, int cpu_no) + { + int res; + +@@ -90,7 +89,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span, + goto umount; + } + +- res = mbm_bw_change(span, cpu_no, bw_report, benchmark_cmd); ++ res = mbm_bw_change(span, cpu_no, benchmark_cmd); + ksft_test_result(!res, "MBM: bw change\n"); + if ((get_vendor() == ARCH_INTEL) && res) + ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n"); +@@ -99,7 +98,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span, + umount_resctrlfs(); + } + +-static void run_mba_test(char **benchmark_cmd, int cpu_no, char *bw_report) ++static void run_mba_test(char **benchmark_cmd, int cpu_no) + { + int res; + +@@ -118,7 +117,7 @@ static void run_mba_test(char **benchmark_cmd, int cpu_no, char *bw_report) + goto umount; + } + +- res = mba_schemata_change(cpu_no, bw_report, benchmark_cmd); ++ res = mba_schemata_change(cpu_no, benchmark_cmd); + ksft_test_result(!res, "MBA: schemata change\n"); + + umount: +@@ -179,9 +178,9 @@ static void run_cat_test(int cpu_no, int no_of_bits) + int main(int argc, char **argv) + { + bool has_ben = false, mbm_test = true, mba_test = true, cmt_test = true; +- char *benchmark_cmd[BENCHMARK_ARGS], bw_report[64], bm_type[64]; + char benchmark_cmd_area[BENCHMARK_ARGS][BENCHMARK_ARG_SIZE]; + int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0; ++ char *benchmark_cmd[BENCHMARK_ARGS]; + int ben_ind, ben_count, tests = 0; + size_t span = 250 * MB; + bool cat_test = true; +@@ -284,9 +283,6 @@ int main(int argc, char **argv) + benchmark_cmd[5] = NULL; + } + +- sprintf(bw_report, "reads"); +- sprintf(bm_type, "fill_buf"); +- + if (!check_resctrlfs_support()) + return ksft_exit_skip("resctrl FS does not exist. Enable X86_CPU_RESCTRL config option.\n"); + +@@ -298,10 +294,10 @@ int main(int argc, char **argv) + ksft_set_plan(tests ? : 4); + + if (mbm_test) +- run_mbm_test(benchmark_cmd, span, cpu_no, bw_report); ++ run_mbm_test(benchmark_cmd, span, cpu_no); + + if (mba_test) +- run_mba_test(benchmark_cmd, cpu_no, bw_report); ++ run_mba_test(benchmark_cmd, cpu_no); + + if (cmt_test) + run_cmt_test(benchmark_cmd, cpu_no); +-- +2.42.0 + diff --git a/queue-6.6/selftests-resctrl-simplify-span-lifetime.patch b/queue-6.6/selftests-resctrl-simplify-span-lifetime.patch new file mode 100644 index 00000000000..30d0f20947c --- /dev/null +++ b/queue-6.6/selftests-resctrl-simplify-span-lifetime.patch @@ -0,0 +1,305 @@ +From 3034595e60cb16e8b4cafd69d9ddeba421bf018a Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 4 Sep 2023 12:53:35 +0300 +Subject: selftests/resctrl: Simplify span lifetime +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Ilpo Järvinen + +[ Upstream commit b1a901e078c4ee4a6fe13021c4577ef5f3155251 ] + +struct resctrl_val_param contains span member. resctrl_val(), however, +never uses it because the value of span is embedded into the default +benchmark command and parsed from it by run_benchmark(). + +Remove span from resctrl_val_param. Provide DEFAULT_SPAN for the code +that needs it. CMT and CAT tests communicate span that is different +from the DEFAULT_SPAN between their internal functions which is +converted into passing it directly as a parameter. + +Signed-off-by: Ilpo Järvinen +Tested-by: Shaopeng Tan +Reviewed-by: Reinette Chatre +Reviewed-by: Shaopeng Tan +Reviewed-by: "Wieczor-Retman, Maciej" +Signed-off-by: Shuah Khan +Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal") +Signed-off-by: Sasha Levin +--- + tools/testing/selftests/resctrl/cache.c | 5 +++-- + tools/testing/selftests/resctrl/cat_test.c | 13 +++++++------ + tools/testing/selftests/resctrl/cmt_test.c | 11 ++++++----- + tools/testing/selftests/resctrl/mbm_test.c | 5 ++--- + tools/testing/selftests/resctrl/resctrl.h | 8 ++++---- + tools/testing/selftests/resctrl/resctrl_tests.c | 9 ++++----- + 6 files changed, 26 insertions(+), 25 deletions(-) + +diff --git a/tools/testing/selftests/resctrl/cache.c b/tools/testing/selftests/resctrl/cache.c +index d3cbb829ff6a7..a0318bd3a63d8 100644 +--- a/tools/testing/selftests/resctrl/cache.c ++++ b/tools/testing/selftests/resctrl/cache.c +@@ -205,10 +205,11 @@ int measure_cache_vals(struct resctrl_val_param *param, int bm_pid) + * cache_val: execute benchmark and measure LLC occupancy resctrl + * and perf cache miss for the benchmark + * @param: parameters passed to cache_val() ++ * @span: buffer size for the benchmark + * + * Return: 0 on success. non-zero on failure. + */ +-int cat_val(struct resctrl_val_param *param) ++int cat_val(struct resctrl_val_param *param, size_t span) + { + int memflush = 1, operation = 0, ret = 0; + char *resctrl_val = param->resctrl_val; +@@ -245,7 +246,7 @@ int cat_val(struct resctrl_val_param *param) + if (ret) + break; + +- if (run_fill_buf(param->span, memflush, operation, true)) { ++ if (run_fill_buf(span, memflush, operation, true)) { + fprintf(stderr, "Error-running fill buffer\n"); + ret = -1; + goto pe_close; +diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c +index 3848dfb46aba4..97b87285ab2a9 100644 +--- a/tools/testing/selftests/resctrl/cat_test.c ++++ b/tools/testing/selftests/resctrl/cat_test.c +@@ -41,7 +41,7 @@ static int cat_setup(struct resctrl_val_param *p) + return ret; + } + +-static int check_results(struct resctrl_val_param *param) ++static int check_results(struct resctrl_val_param *param, size_t span) + { + char *token_array[8], temp[512]; + unsigned long sum_llc_perf_miss = 0; +@@ -76,7 +76,7 @@ static int check_results(struct resctrl_val_param *param) + fclose(fp); + no_of_bits = count_bits(param->mask); + +- return show_cache_info(sum_llc_perf_miss, no_of_bits, param->span / 64, ++ return show_cache_info(sum_llc_perf_miss, no_of_bits, span / 64, + MAX_DIFF, MAX_DIFF_PERCENT, runs - 1, + get_vendor() == ARCH_INTEL, false); + } +@@ -96,6 +96,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + char cbm_mask[256]; + int count_of_bits; + char pipe_message; ++ size_t span; + + /* Get default cbm mask for L3/L2 cache */ + ret = get_cbm_mask(cache_type, cbm_mask); +@@ -140,7 +141,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + /* Set param values for parent thread which will be allocated bitmask + * with (max_bits - n) bits + */ +- param.span = cache_size * (count_of_bits - n) / count_of_bits; ++ span = cache_size * (count_of_bits - n) / count_of_bits; + strcpy(param.ctrlgrp, "c2"); + strcpy(param.mongrp, "m2"); + strcpy(param.filename, RESULT_FILE_NAME2); +@@ -162,7 +163,7 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + param.mask = l_mask_1; + strcpy(param.ctrlgrp, "c1"); + strcpy(param.mongrp, "m1"); +- param.span = cache_size * n / count_of_bits; ++ span = cache_size * n / count_of_bits; + strcpy(param.filename, RESULT_FILE_NAME1); + param.num_of_runs = 0; + param.cpu_no = sibling_cpu_no; +@@ -176,9 +177,9 @@ int cat_perf_miss_val(int cpu_no, int n, char *cache_type) + + remove(param.filename); + +- ret = cat_val(¶m); ++ ret = cat_val(¶m, span); + if (ret == 0) +- ret = check_results(¶m); ++ ret = check_results(¶m, span); + + if (bm_pid == 0) { + /* Tell parent that child is ready */ +diff --git a/tools/testing/selftests/resctrl/cmt_test.c b/tools/testing/selftests/resctrl/cmt_test.c +index cc93cb5ae7ee9..33dbe51e77122 100644 +--- a/tools/testing/selftests/resctrl/cmt_test.c ++++ b/tools/testing/selftests/resctrl/cmt_test.c +@@ -27,7 +27,7 @@ static int cmt_setup(struct resctrl_val_param *p) + return 0; + } + +-static int check_results(struct resctrl_val_param *param, int no_of_bits) ++static int check_results(struct resctrl_val_param *param, size_t span, int no_of_bits) + { + char *token_array[8], temp[512]; + unsigned long sum_llc_occu_resc = 0; +@@ -58,7 +58,7 @@ static int check_results(struct resctrl_val_param *param, int no_of_bits) + } + fclose(fp); + +- return show_cache_info(sum_llc_occu_resc, no_of_bits, param->span, ++ return show_cache_info(sum_llc_occu_resc, no_of_bits, span, + MAX_DIFF, MAX_DIFF_PERCENT, runs - 1, + true, true); + } +@@ -74,6 +74,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) + unsigned long long_mask; + char cbm_mask[256]; + int count_of_bits; ++ size_t span; + int ret; + + ret = get_cbm_mask("L3", cbm_mask); +@@ -102,13 +103,13 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) + .cpu_no = cpu_no, + .filename = RESULT_FILE_NAME, + .mask = ~(long_mask << n) & long_mask, +- .span = cache_size * n / count_of_bits, + .num_of_runs = 0, + .setup = cmt_setup, + }; + ++ span = cache_size * n / count_of_bits; + if (strcmp(benchmark_cmd[0], "fill_buf") == 0) +- sprintf(benchmark_cmd[1], "%zu", param.span); ++ sprintf(benchmark_cmd[1], "%zu", span); + + remove(RESULT_FILE_NAME); + +@@ -116,7 +117,7 @@ int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd) + if (ret) + goto out; + +- ret = check_results(¶m, n); ++ ret = check_results(¶m, span, n); + + out: + cmt_test_cleanup(); +diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c +index 724412186d636..445aea1c64e83 100644 +--- a/tools/testing/selftests/resctrl/mbm_test.c ++++ b/tools/testing/selftests/resctrl/mbm_test.c +@@ -109,13 +109,12 @@ void mbm_test_cleanup(void) + remove(RESULT_FILE_NAME); + } + +-int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd) ++int mbm_bw_change(int cpu_no, char **benchmark_cmd) + { + struct resctrl_val_param param = { + .resctrl_val = MBM_STR, + .ctrlgrp = "c1", + .mongrp = "m1", +- .span = span, + .cpu_no = cpu_no, + .filename = RESULT_FILE_NAME, + .bw_report = "reads", +@@ -129,7 +128,7 @@ int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd) + if (ret) + goto out; + +- ret = check_results(span); ++ ret = check_results(DEFAULT_SPAN); + + out: + mbm_test_cleanup(); +diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h +index df75c89060329..d33452fde5b94 100644 +--- a/tools/testing/selftests/resctrl/resctrl.h ++++ b/tools/testing/selftests/resctrl/resctrl.h +@@ -33,6 +33,8 @@ + + #define END_OF_TESTS 1 + ++#define DEFAULT_SPAN (250 * MB) ++ + #define PARENT_EXIT(err_msg) \ + do { \ + perror(err_msg); \ +@@ -47,7 +49,6 @@ + * @ctrlgrp: Name of the control monitor group (con_mon grp) + * @mongrp: Name of the monitor group (mon grp) + * @cpu_no: CPU number to which the benchmark would be binded +- * @span: Memory bytes accessed in each benchmark iteration + * @filename: Name of file to which the o/p should be written + * @bw_report: Bandwidth report type (reads vs writes) + * @setup: Call back function to setup test environment +@@ -57,7 +58,6 @@ struct resctrl_val_param { + char ctrlgrp[64]; + char mongrp[64]; + int cpu_no; +- size_t span; + char filename[64]; + char *bw_report; + unsigned long mask; +@@ -93,7 +93,7 @@ int perf_event_open(struct perf_event_attr *hw_event, pid_t pid, int cpu, + int group_fd, unsigned long flags); + int run_fill_buf(size_t span, int memflush, int op, bool once); + int resctrl_val(char **benchmark_cmd, struct resctrl_val_param *param); +-int mbm_bw_change(size_t span, int cpu_no, char **benchmark_cmd); ++int mbm_bw_change(int cpu_no, char **benchmark_cmd); + void tests_cleanup(void); + void mbm_test_cleanup(void); + int mba_schemata_change(int cpu_no, char **benchmark_cmd); +@@ -103,7 +103,7 @@ int get_cache_size(int cpu_no, char *cache_type, unsigned long *cache_size); + void ctrlc_handler(int signum, siginfo_t *info, void *ptr); + int signal_handler_register(void); + void signal_handler_unregister(void); +-int cat_val(struct resctrl_val_param *param); ++int cat_val(struct resctrl_val_param *param, size_t span); + void cat_test_cleanup(void); + int cat_perf_miss_val(int cpu_no, int no_of_bits, char *cache_type); + int cmt_resctrl_val(int cpu_no, int n, char **benchmark_cmd); +diff --git a/tools/testing/selftests/resctrl/resctrl_tests.c b/tools/testing/selftests/resctrl/resctrl_tests.c +index 116f67d833f75..1826b674ea300 100644 +--- a/tools/testing/selftests/resctrl/resctrl_tests.c ++++ b/tools/testing/selftests/resctrl/resctrl_tests.c +@@ -70,7 +70,7 @@ void tests_cleanup(void) + cat_test_cleanup(); + } + +-static void run_mbm_test(char **benchmark_cmd, size_t span, int cpu_no) ++static void run_mbm_test(char **benchmark_cmd, int cpu_no) + { + int res; + +@@ -89,7 +89,7 @@ static void run_mbm_test(char **benchmark_cmd, size_t span, int cpu_no) + goto umount; + } + +- res = mbm_bw_change(span, cpu_no, benchmark_cmd); ++ res = mbm_bw_change(cpu_no, benchmark_cmd); + ksft_test_result(!res, "MBM: bw change\n"); + if ((get_vendor() == ARCH_INTEL) && res) + ksft_print_msg("Intel MBM may be inaccurate when Sub-NUMA Clustering is enabled. Check BIOS configuration.\n"); +@@ -182,7 +182,6 @@ int main(int argc, char **argv) + int c, cpu_no = 1, argc_new = argc, i, no_of_bits = 0; + char *benchmark_cmd[BENCHMARK_ARGS]; + int ben_ind, ben_count, tests = 0; +- size_t span = 250 * MB; + bool cat_test = true; + + for (i = 0; i < argc; i++) { +@@ -276,7 +275,7 @@ int main(int argc, char **argv) + benchmark_cmd[i] = benchmark_cmd_area[i]; + + strcpy(benchmark_cmd[0], "fill_buf"); +- sprintf(benchmark_cmd[1], "%zu", span); ++ sprintf(benchmark_cmd[1], "%u", DEFAULT_SPAN); + strcpy(benchmark_cmd[2], "1"); + strcpy(benchmark_cmd[3], "0"); + strcpy(benchmark_cmd[4], "false"); +@@ -294,7 +293,7 @@ int main(int argc, char **argv) + ksft_set_plan(tests ? : 4); + + if (mbm_test) +- run_mbm_test(benchmark_cmd, span, cpu_no); ++ run_mbm_test(benchmark_cmd, cpu_no); + + if (mba_test) + run_mba_test(benchmark_cmd, cpu_no); +-- +2.42.0 + diff --git a/queue-6.6/series b/queue-6.6/series index 00a2e20567f..0a5a160bb95 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -390,3 +390,22 @@ i3c-master-svc-fix-ibi-may-not-return-mandatory-data-byte.patch i3c-master-svc-fix-check-wrong-status-register-in-irq-handler.patch i3c-master-svc-fix-sda-keep-low-when-polling-ibiwon-timeout-happen.patch i3c-master-svc-fix-random-hot-join-failure-since-timeout-error.patch +apparmor-fix-kernel-doc-warnings-in-apparmor-audit.c.patch +apparmor-fix-kernel-doc-warnings-in-apparmor-lib.c.patch +apparmor-fix-kernel-doc-warnings-in-apparmor-resourc.patch +apparmor-fix-kernel-doc-warnings-in-apparmor-policy..patch +apparmor-combine-common_audit_data-and-apparmor_audi.patch +apparmor-rename-audit_data-label-to-audit_data-subj_.patch +apparmor-pass-cred-through-to-audit-info.patch +apparmor-fix-regression-in-mount-mediation.patch +bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch +bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch +drm-amd-display-enable-dsc_clk-even-if-dsc_pg-disabl.patch +torture-make-torture_hrtimeout_ns-take-an-hrtimer-mo.patch +rcutorture-fix-stuttering-races-and-other-issues.patch +selftests-resctrl-remove-bw_report-and-bm_type-from-.patch +selftests-resctrl-simplify-span-lifetime.patch +selftests-resctrl-make-benchmark-command-const-and-b.patch +selftests-resctrl-extend-signal-handler-coverage-to-.patch +cxl-region-fix-x1-root-decoder-granularity-calculati.patch +cxl-port-fix-delete_endpoint-vs-parent-unregistratio.patch diff --git a/queue-6.6/torture-make-torture_hrtimeout_ns-take-an-hrtimer-mo.patch b/queue-6.6/torture-make-torture_hrtimeout_ns-take-an-hrtimer-mo.patch new file mode 100644 index 00000000000..af47e7c7b01 --- /dev/null +++ b/queue-6.6/torture-make-torture_hrtimeout_ns-take-an-hrtimer-mo.patch @@ -0,0 +1,100 @@ +From 42cec578f5f387699165906a7ab1eb12daaa55d4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 26 Jul 2023 13:57:03 -0700 +Subject: torture: Make torture_hrtimeout_ns() take an hrtimer mode parameter + +From: Paul E. McKenney + +[ Upstream commit a741deac787f0d2d7068638c067db20af9e63752 ] + +The current torture-test sleeps are waiting for a duration, but there +are situations where it is better to wait for an absolute time, for +example, when ending a stutter interval. This commit therefore adds +an hrtimer mode parameter to torture_hrtimeout_ns(). Why not also the +other torture_hrtimeout_*() functions? The theory is that most absolute +times will be in nanoseconds, especially not (say) jiffies. + +Signed-off-by: Paul E. McKenney +Signed-off-by: Frederic Weisbecker +Stable-dep-of: cca42bd8eb1b ("rcutorture: Fix stuttering races and other issues") +Signed-off-by: Sasha Levin +--- + include/linux/torture.h | 3 ++- + kernel/torture.c | 13 +++++++------ + 2 files changed, 9 insertions(+), 7 deletions(-) + +diff --git a/include/linux/torture.h b/include/linux/torture.h +index bb466eec01e42..017f0f710815a 100644 +--- a/include/linux/torture.h ++++ b/include/linux/torture.h +@@ -81,7 +81,8 @@ static inline void torture_random_init(struct torture_random_state *trsp) + } + + /* Definitions for high-resolution-timer sleeps. */ +-int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, struct torture_random_state *trsp); ++int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, const enum hrtimer_mode mode, ++ struct torture_random_state *trsp); + int torture_hrtimeout_us(u32 baset_us, u32 fuzzt_ns, struct torture_random_state *trsp); + int torture_hrtimeout_ms(u32 baset_ms, u32 fuzzt_us, struct torture_random_state *trsp); + int torture_hrtimeout_jiffies(u32 baset_j, struct torture_random_state *trsp); +diff --git a/kernel/torture.c b/kernel/torture.c +index b28b05bbef027..e851b8e9390b3 100644 +--- a/kernel/torture.c ++++ b/kernel/torture.c +@@ -87,14 +87,15 @@ EXPORT_SYMBOL_GPL(verbose_torout_sleep); + * nanosecond random fuzz. This function and its friends desynchronize + * testing from the timer wheel. + */ +-int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, struct torture_random_state *trsp) ++int torture_hrtimeout_ns(ktime_t baset_ns, u32 fuzzt_ns, const enum hrtimer_mode mode, ++ struct torture_random_state *trsp) + { + ktime_t hto = baset_ns; + + if (trsp) + hto += torture_random(trsp) % fuzzt_ns; + set_current_state(TASK_IDLE); +- return schedule_hrtimeout(&hto, HRTIMER_MODE_REL); ++ return schedule_hrtimeout(&hto, mode); + } + EXPORT_SYMBOL_GPL(torture_hrtimeout_ns); + +@@ -106,7 +107,7 @@ int torture_hrtimeout_us(u32 baset_us, u32 fuzzt_ns, struct torture_random_state + { + ktime_t baset_ns = baset_us * NSEC_PER_USEC; + +- return torture_hrtimeout_ns(baset_ns, fuzzt_ns, trsp); ++ return torture_hrtimeout_ns(baset_ns, fuzzt_ns, HRTIMER_MODE_REL, trsp); + } + EXPORT_SYMBOL_GPL(torture_hrtimeout_us); + +@@ -123,7 +124,7 @@ int torture_hrtimeout_ms(u32 baset_ms, u32 fuzzt_us, struct torture_random_state + fuzzt_ns = (u32)~0U; + else + fuzzt_ns = fuzzt_us * NSEC_PER_USEC; +- return torture_hrtimeout_ns(baset_ns, fuzzt_ns, trsp); ++ return torture_hrtimeout_ns(baset_ns, fuzzt_ns, HRTIMER_MODE_REL, trsp); + } + EXPORT_SYMBOL_GPL(torture_hrtimeout_ms); + +@@ -136,7 +137,7 @@ int torture_hrtimeout_jiffies(u32 baset_j, struct torture_random_state *trsp) + { + ktime_t baset_ns = jiffies_to_nsecs(baset_j); + +- return torture_hrtimeout_ns(baset_ns, jiffies_to_nsecs(1), trsp); ++ return torture_hrtimeout_ns(baset_ns, jiffies_to_nsecs(1), HRTIMER_MODE_REL, trsp); + } + EXPORT_SYMBOL_GPL(torture_hrtimeout_jiffies); + +@@ -153,7 +154,7 @@ int torture_hrtimeout_s(u32 baset_s, u32 fuzzt_ms, struct torture_random_state * + fuzzt_ns = (u32)~0U; + else + fuzzt_ns = fuzzt_ms * NSEC_PER_MSEC; +- return torture_hrtimeout_ns(baset_ns, fuzzt_ns, trsp); ++ return torture_hrtimeout_ns(baset_ns, fuzzt_ns, HRTIMER_MODE_REL, trsp); + } + EXPORT_SYMBOL_GPL(torture_hrtimeout_s); + +-- +2.42.0 +