{
  "affected": [
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:12",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:13",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    },
    {
      "ecosystem_specific": {
        "urgency": "not yet assigned"
      },
      "package": {
        "ecosystem": "Debian:14",
        "name": "linux"
      },
      "ranges": [
        {
          "events": [
            {
              "introduced": "0"
            }
          ],
          "type": "ECOSYSTEM"
        }
      ]
    }
  ],
  "details": "In the Linux kernel, the following vulnerability has been resolved:  apparmor: fix cred UAF caused by begin_current_label_crit_section()  AppArmor's begin_current_label_crit_section() is a scary function called from lots of LSM hooks (in particular VFS/socket-related ones) that checks if the label referenced by the current creds is marked FLAG_STALE, and if so, attempts to use aa_replace_current_label() to replace the creds with an updated version that uses a new label.  The first problem with this is that it would directly lead to UAF of `struct cred` if anything in the kernel takes a pointer to the current creds and accesses these past a security hook invocation that replaces creds, like so: ``` const struct cred *cred = current_cred(); alloc_file_pseudo(...); uid_t uid = cred-\u003eeuid; ``` I don't know if anything in the kernel actually does this, but I think it is very surprising that this pattern could lead to UAF.  The second problem is that things go wrong when aa_replace_current_label() runs with overridden credentials. aa_replace_current_label() bails out if `current_cred() != current_real_cred()` (mirroring the check in proc_pid_attr_write()), but this check can't actually reliably detect overridden credentials because the overridden creds can be the same as the objective creds.  So in approximately the following scenario, things go wrong:  1. task begins with \u003ccreds A\u003e (as both objective and subjective creds),    with refcount=2 2. task grabs an extra reference on \u003ccreds A\u003e for overriding 3. task calls override_creds(\u003ccreds A\u003e), which returns a pointer to the old    subjective creds (\u003ccreds A\u003e) 4. task enters AppArmor LSM hook 5. AppArmor checks that objective/subjective creds are equal 6. AppArmor replaces both cred pointers with \u003ccreds B\u003e and drops 2 refs on    \u003ccreds A\u003e 7. task leaves AppArmor LSM hook 8. task calls revert_creds(\u003ccreds A\u003e) 9. now task-\u003ecred is \u003ccreds A\u003e while task-\u003ereal_cred is \u003ccreds B\u003e, but the    task_struct logically holds two references to \u003ccreds B\u003e 10. another task drops the extra reference on \u003ccreds A\u003e that was used for     overriding, refcount drops to 0 11. now task-\u003ereal_cred points to freed creds  At this point, any access to current_cred() will be UAF.  I have a test case where I run aa-disable on a profile while a process using that profile is blocked on splice() from a FUSE passthrough file into a full pipe; after the profile update, the pipe becomes empty, splice() resumes, the credentials go out of sync, and a subsequent getuid() syscall results in a KASAN UAF splat.  To fix this, instead of directly replacing creds, do it via task_work that will run at the end of the current syscall. (The point in time at which the cred replacement happens should have no correctness impact; it is just a performance optimization to avoid unnecessarily touching the refcount of the new label.)  Note that AppArmor still performs direct cred replacements in the sb_pivotroot LSM hook after this change, and that direct cred replacements can still happen in VFS -\u003ewrite() callbacks via proc_pid_attr_write().  There are two options for what to do with aa_dup_task_ctx(): Either explicitly reset new-\u003elabel_replacement_pending after the entire aa_task_ctx has been copied, or switch to manually copying members over. I am switching to manually copying members over because that should make bugs more obvious.",
  "id": "DEBIAN-CVE-2026-89762",
  "modified": "2026-09-14T08:47:41.489195242Z",
  "published": "2026-09-11T20:20:07.377Z",
  "references": [
    {
      "type": "ADVISORY",
      "url": "https://security-tracker.debian.org/tracker/CVE-2026-89762"
    }
  ],
  "severity": [
    {
      "score": "CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
      "type": "CVSS_V3"
    }
  ],
  "upstream": [
    "CVE-2026-89762"
  ]
}