]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 6.6
authorSasha Levin <sashal@kernel.org>
Fri, 24 Nov 2023 04:28:38 +0000 (23:28 -0500)
committerSasha Levin <sashal@kernel.org>
Fri, 24 Nov 2023 04:28:38 +0000 (23:28 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
20 files changed:
queue-6.6/apparmor-combine-common_audit_data-and-apparmor_audi.patch [new file with mode: 0644]
queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-audit.c.patch [new file with mode: 0644]
queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-lib.c.patch [new file with mode: 0644]
queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-policy..patch [new file with mode: 0644]
queue-6.6/apparmor-fix-kernel-doc-warnings-in-apparmor-resourc.patch [new file with mode: 0644]
queue-6.6/apparmor-fix-regression-in-mount-mediation.patch [new file with mode: 0644]
queue-6.6/apparmor-pass-cred-through-to-audit-info.patch [new file with mode: 0644]
queue-6.6/apparmor-rename-audit_data-label-to-audit_data-subj_.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-add-0bda-b85b-for-fn-link-rtl8852be.patch [new file with mode: 0644]
queue-6.6/bluetooth-btusb-add-rtw8852be-device-13d3-3570-to-de.patch [new file with mode: 0644]
queue-6.6/cxl-port-fix-delete_endpoint-vs-parent-unregistratio.patch [new file with mode: 0644]
queue-6.6/cxl-region-fix-x1-root-decoder-granularity-calculati.patch [new file with mode: 0644]
queue-6.6/drm-amd-display-enable-dsc_clk-even-if-dsc_pg-disabl.patch [new file with mode: 0644]
queue-6.6/rcutorture-fix-stuttering-races-and-other-issues.patch [new file with mode: 0644]
queue-6.6/selftests-resctrl-extend-signal-handler-coverage-to-.patch [new file with mode: 0644]
queue-6.6/selftests-resctrl-make-benchmark-command-const-and-b.patch [new file with mode: 0644]
queue-6.6/selftests-resctrl-remove-bw_report-and-bm_type-from-.patch [new file with mode: 0644]
queue-6.6/selftests-resctrl-simplify-span-lifetime.patch [new file with mode: 0644]
queue-6.6/series
queue-6.6/torture-make-torture_hrtimeout_ns-take-an-hrtimer-mo.patch [new file with mode: 0644]

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 (file)
index 0000000..ded3f81
--- /dev/null
@@ -0,0 +1,1183 @@
+From bf8c7a978ba2ae5754a2d81f3137492066926f0e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 14 Sep 2022 00:20:12 -0700
+Subject: apparmor: combine common_audit_data and apparmor_audit_data
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ 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 <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <profile, profile, perm> */
+       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 (file)
index 0000000..a082e71
--- /dev/null
@@ -0,0 +1,37 @@
+From e0d838f05b6f88582e1c6b8dc29c7fcd9ce9499e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:39 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/audit.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ 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 <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..c83c738
--- /dev/null
@@ -0,0 +1,60 @@
+From b6cd9b4ada4e9bde21363488ef32f08e5a3c60d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:44 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/lib.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ 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 <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..b497076
--- /dev/null
@@ -0,0 +1,90 @@
+From 274b48aa36c1e1f1288375fff31d49a9eb40485f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:49 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/policy.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ 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 <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..44a1bd8
--- /dev/null
@@ -0,0 +1,50 @@
+From 1fa4cbf9881993c63ffe88134a97c923d9434437 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 25 Jun 2023 09:13:46 +0800
+Subject: apparmor: Fix kernel-doc warnings in apparmor/resource.c
+
+From: Gaosheng Cui <cuigaosheng1@huawei.com>
+
+[ 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 <cuigaosheng1@huawei.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..7f8a8b0
--- /dev/null
@@ -0,0 +1,165 @@
+From 9da47efe8ca49d251e3bd334c61d6bcdb215c51a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 10 Sep 2023 03:35:22 -0700
+Subject: apparmor: Fix regression in mount mediation
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ 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 <anstein99@googlemail.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..9ac7f20
--- /dev/null
@@ -0,0 +1,1933 @@
+From 6868e7132f91ab9266f4c4f2ae645a42a5a089cc Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Sep 2022 20:48:48 -0700
+Subject: apparmor: pass cred through to audit info.
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ 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 <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 <linux/sched.h>
+-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 <profile, profile, perm> */
+       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 (file)
index 0000000..7c4a7fe
--- /dev/null
@@ -0,0 +1,223 @@
+From 1df12c1710f6af2f580f6cffecd20d981358a372 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 19 Sep 2022 00:46:09 -0700
+Subject: apparmor: rename audit_data->label to audit_data->subj_label
+
+From: John Johansen <john.johansen@canonical.com>
+
+[ 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 <georgia.garcia@canonical.com>
+Signed-off-by: John Johansen <john.johansen@canonical.com>
+Stable-dep-of: 157a3537d6bc ("apparmor: Fix regression in mount mediation")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..61b7669
--- /dev/null
@@ -0,0 +1,75 @@
+From c093b26521e8af0928c5d725c505409e1920066d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 12 Oct 2023 19:21:17 +0800
+Subject: Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE
+
+From: Guan Wentao <guanwentao@uniontech.com>
+
+[ 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 <tangmeng@uniontech.com>
+Signed-off-by: Guan Wentao <guanwentao@uniontech.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..c5f67d7
--- /dev/null
@@ -0,0 +1,68 @@
+From 83cbff78bef8ab61bad6f1513462e5338b832b14 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sun, 24 Sep 2023 16:46:55 +0530
+Subject: Bluetooth: btusb: Add RTW8852BE device 13d3:3570 to device tables
+
+From: Masum Reza <masumrezarock100@gmail.com>
+
+[ 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 <masumrezarock100@gmail.com>
+Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
+Stable-dep-of: da06ff1f585e ("Bluetooth: btusb: Add 0bda:b85b for Fn-Link RTL8852BE")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..af69a88
--- /dev/null
@@ -0,0 +1,121 @@
+From 1fb8159e9c2490c44b8cf3061ec4b7598ed0cb7d Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 27 Oct 2023 20:13:23 -0700
+Subject: cxl/port: Fix delete_endpoint() vs parent unregistration race
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+[ 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: <stable@vger.kernel.org>
+Reported-by: Robert Richter <rrichter@amd.com>
+Closes: http://lore.kernel.org/r/20231018171713.1883517-2-rrichter@amd.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..3dec3d4
--- /dev/null
@@ -0,0 +1,93 @@
+From 81d1fc2e5b8aa62e8d1ca5524b89b8e25127f2dd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 26 Oct 2023 10:09:06 -0700
+Subject: cxl/region: Fix x1 root-decoder granularity calculations
+
+From: Jim Harris <jim.harris@samsung.com>
+
+[ 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: <stable@vger.kernel.org>
+Signed-off-by: Jim Harris <jim.harris@samsung.com>
+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 <dan.j.williams@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..7db39a0
--- /dev/null
@@ -0,0 +1,83 @@
+From fb508286dd45a6c20533ea1da620dc625fca6b47 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 18 Sep 2023 16:52:54 -0400
+Subject: drm/amd/display: enable dsc_clk even if dsc_pg disabled
+
+From: Muhammad Ahmed <ahmed.ahmed@amd.com>
+
+[ Upstream commit 40255df370e94d44f0f0a924400d68db0ee31bec ]
+
+[why]
+need to enable dsc_clk regardless dsc_pg
+
+Reviewed-by: Charlene Liu <charlene.liu@amd.com>
+Cc: Mario Limonciello <mario.limonciello@amd.com>
+Cc: Alex Deucher <alexander.deucher@amd.com>
+Cc: stable@vger.kernel.org
+Acked-by: Aurabindo Pillai <aurabindo.pillai@amd.com>
+Signed-off-by: Muhammad Ahmed <ahmed.ahmed@amd.com>
+Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
+Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..828d20e
--- /dev/null
@@ -0,0 +1,127 @@
+From 6b13da968c234929a21e3dc1e7120e617481ad86 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 29 Jul 2023 14:27:31 +0000
+Subject: rcutorture: Fix stuttering races and other issues
+
+From: Joel Fernandes (Google) <joel@joelfernandes.org>
+
+[ 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) <joel@joelfernandes.org>
+Signed-off-by: Paul E. McKenney <paulmck@kernel.org>
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..4e78af5
--- /dev/null
@@ -0,0 +1,320 @@
+From c57c67ed524ea6affabaeeeb4aee3e7d60b9386b Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <ilpo.jarvinen@linux.intel.com>
+
+[ 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 <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..ee87d60
--- /dev/null
@@ -0,0 +1,293 @@
+From 06be35495ce0e4f598017fc4324198595deed4bd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <ilpo.jarvinen@linux.intel.com>
+
+[ 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 <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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, &param);
++      ret = resctrl_val(cmd, &param);
+       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 (file)
index 0000000..2379345
--- /dev/null
@@ -0,0 +1,171 @@
+From 9d927dab1a26936dae56d5e161f55f57358b70a2 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <ilpo.jarvinen@linux.intel.com>
+
+[ 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 <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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 (file)
index 0000000..30d0f20
--- /dev/null
@@ -0,0 +1,305 @@
+From 3034595e60cb16e8b4cafd69d9ddeba421bf018a Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+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 <ilpo.jarvinen@linux.intel.com>
+
+[ 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 <ilpo.jarvinen@linux.intel.com>
+Tested-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: Reinette Chatre <reinette.chatre@intel.com>
+Reviewed-by: Shaopeng Tan <tan.shaopeng@jp.fujitsu.com>
+Reviewed-by: "Wieczor-Retman, Maciej" <maciej.wieczor-retman@intel.com>
+Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>
+Stable-dep-of: 3aff51464455 ("selftests/resctrl: Extend signal handler coverage to unmount on receiving signal")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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(&param);
++      ret = cat_val(&param, span);
+       if (ret == 0)
+-              ret = check_results(&param);
++              ret = check_results(&param, 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(&param, n);
++      ret = check_results(&param, 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
+
index 00a2e20567f92f13530eb16fbc2a771039d24cd3..0a5a160bb95ca5aafcaf83410c96852e4b233769 100644 (file)
@@ -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 (file)
index 0000000..af47e7c
--- /dev/null
@@ -0,0 +1,100 @@
+From 42cec578f5f387699165906a7ab1eb12daaa55d4 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 26 Jul 2023 13:57:03 -0700
+Subject: torture: Make torture_hrtimeout_ns() take an hrtimer mode parameter
+
+From: Paul E. McKenney <paulmck@kernel.org>
+
+[ 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 <paulmck@kernel.org>
+Signed-off-by: Frederic Weisbecker <frederic@kernel.org>
+Stable-dep-of: cca42bd8eb1b ("rcutorture: Fix stuttering races and other issues")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ 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
+