Lucene search
+L

Unity Linux 20.1050a Security Update: kernel (UTSA-2026-146629)

🗓️ 28 Oct 2026 00:00:00Reported by TenableType 
nessus
 nessus
🔗 www.tenable.com👁 3 Views

Use-after-free in Linux kernel AppArmor's begin_current_label_crit_section() function.

Related
Refs
Code
#%NASL_MIN_LEVEL 80900
##
# (C) Tenable, Inc.
##

include('compat.inc');

if (description)
{
  script_id(373177);
  script_version("1.1");
  script_set_attribute(attribute:"plugin_modification_date", value:"2026/10/28");

  script_cve_id("CVE-2026-89762");

  script_name(english:"Unity Linux 20.1050a Security Update: kernel (UTSA-2026-146629)");

  script_set_attribute(attribute:"synopsis", value:
"The Unity Linux host is missing one or more security updates.");
  script_set_attribute(attribute:"description", value:
"The Unity Linux 20 host has a package installed that is affected by a vulnerability as referenced in the
UTSA-2026-146629 advisory.

    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->euid;
    ```
    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 <creds A> (as both objective and subjective creds),
       with refcount=2
    2. task grabs an extra reference on <creds A> for overriding
    3. task calls override_creds(<creds A>), which returns a pointer to the old
       subjective creds (<creds A>)
    4. task enters AppArmor LSM hook
    5. AppArmor checks that objective/subjective creds are equal
    6. AppArmor replaces both cred pointers with <creds B> and drops 2 refs on
       <creds A>
    7. task leaves AppArmor LSM hook
    8. task calls revert_creds(<creds A>)
    9. now task->cred is <creds A> while task->real_cred is <creds B>, but the
       task_struct logically holds two references to <creds B>
    10. another task drops the extra reference on <creds A> that was used for
        overriding, refcount drops to 0
    11. now task->real_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 ->write() callbacks via proc_pid_attr_write().

    There are two options for what to do with aa_dup_task_ctx(): Either
    explicitly reset new->label_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.

Tenable has extracted the preceding description block directly from the Unity Linux security advisory.

Note that Nessus has not tested for this issue but has instead relied only on the application's self-reported version
number.");
  # https://src.uniontech.com/#/security_advisory_detail?utsa_id=UTSA-2026-146629
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?c737c942");
  # https://lore.kernel.org/linux-cve-announce/2026091109-CVE-2026-89762-4aa8@gregkh
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?9494dc33");
  script_set_attribute(attribute:"see_also", value:"https://nvd.nist.gov/vuln/detail/CVE-2026-89762");
  script_set_attribute(attribute:"solution", value:
"Update the affected kernel package.");
  script_set_cvss_base_vector("CVSS2#AV:L/AC:L/Au:S/C:C/I:C/A:C");
  script_set_cvss_temporal_vector("CVSS2#E:U/RL:OF/RC:C");
  script_set_cvss3_base_vector("CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H");
  script_set_cvss3_temporal_vector("CVSS:3.0/E:U/RL:O/RC:C");
  script_set_attribute(attribute:"cvss_score_source", value:"CVE-2026-89762");

  script_set_attribute(attribute:"exploitability_ease", value:"No known exploits are available");
  script_set_attribute(attribute:"exploit_available", value:"false");

  script_set_attribute(attribute:"vuln_publication_date", value:"2026/09/11");
  script_set_attribute(attribute:"patch_publication_date", value:"2026/10/28");
  script_set_attribute(attribute:"plugin_publication_date", value:"2026/10/28");

  script_set_attribute(attribute:"plugin_type", value:"local");
  script_set_attribute(attribute:"generated_plugin", value:"current");
  script_end_attributes();

  script_category(ACT_GATHER_INFO);
  script_family(english:"Unity Linux Local Security Checks");

  script_copyright(english:"This script is Copyright (C) 2026 and is owned by Tenable, Inc. or an Affiliate thereof.");

  script_dependencies("ssh_get_info2.nasl");
  script_require_keys("Host/local_checks_enabled", "Host/UOS-Server/release", "Host/UOS-Server/rpm-list", "Host/cpu");

  exit(0);
}
include('rpm2.inc');

if (!get_kb_item('Host/local_checks_enabled')) audit(AUDIT_LOCAL_CHECKS_NOT_ENABLED);
var os_product = get_kb_item('installed_os/local/SSH/0/product');
if (isnull(os_product) || 'UOS Server' >!< os_product) audit(AUDIT_OS_NOT, 'UOS Server');
var os_version = get_kb_item('installed_os/local/SSH/0/version');
if (isnull(os_version)) audit(AUDIT_UNKNOWN_APP_VER, 'UOS Server');
if (! preg(pattern:"^(20.1050a)([^0-9]|$)", string:os_version)) audit(AUDIT_OS_NOT, 'UOS Server 20.1050a', 'UOS Server ' + os_version);

if (!get_kb_item('Host/UOS-Server/rpm-list')) audit(AUDIT_PACKAGE_LIST_MISSING);

var cpu = get_kb_item('Host/cpu');
if (isnull(cpu)) audit(AUDIT_UNKNOWN_ARCH);
if ('aarch64' >!< cpu && 'amd64' >!< cpu && 'loongarch64' >!< cpu && 'x86_64' >!< cpu) audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, 'UOS Server', cpu);


var constraints = [
  {
    'release': '20',
    'sp': '1050a',
    'pkgs': [
      {'reference':'kernel-4.19.0-91.82.132.24.uelc20', 'sp':'1050a', 'cpu':'aarch64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-4.19.0-91.82.132.24.uelc20', 'sp':'1050a', 'cpu':'amd64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-4.19.0-91.82.132.24.uelc20', 'sp':'1050a', 'cpu':'loongarch64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-4.19.0-91.82.132.24.uelc20', 'sp':'1050a', 'cpu':'x86_64', 'rpm_spec_vers_cmp':TRUE}
    ]
  }
];

var os_release = get_one_kb_item('installed_os/local/SSH/0/release');
var os_sp = get_one_kb_item('Host/*/minor_release');

var flag = 0;
var reference;
var sp;
var _cpu;
var el_string;
var rpm_spec_vers_cmp;
var epoch;
var allowmaj;
var exists_check;
var cves;
foreach var constraint ( constraints ) {
  # Check that the target release is equal to the affected release
  if (!empty_or_null(constraint['release'])){
    if (constraint['release'] != os_release) continue;
  }
  if (!empty_or_null(constraint['sp'])){
    if (constraint['sp'] != os_sp) continue;
  }
  foreach var pkg ( constraint['pkgs'] ) {
    reference = NULL;
    sp = NULL;
    _cpu = NULL;
    el_string = NULL;
    rpm_spec_vers_cmp = NULL;
    epoch = NULL;
    allowmaj = NULL;
    exists_check = NULL;
    cves = NULL;
    if (!empty_or_null(pkg['reference'])) reference = pkg['reference'];
    if (!empty_or_null(pkg['sp'])) sp = pkg['sp'];
    if (!empty_or_null(pkg['cpu'])) _cpu = pkg['cpu'];
    if (!empty_or_null(pkg['el_string'])) el_string = pkg['el_string'];
    if (!empty_or_null(pkg['rpm_spec_vers_cmp'])) rpm_spec_vers_cmp = pkg['rpm_spec_vers_cmp'];
    if (!empty_or_null(pkg['epoch'])) epoch = pkg['epoch'];
    if (!empty_or_null(pkg['allowmaj'])) allowmaj = pkg['allowmaj'];
    if (!empty_or_null(pkg['exists_check'])) exists_check = pkg['exists_check'];
    if (!empty_or_null(pkg['cves'])) cves = pkg['cves'];
    if (reference &&
        ## (no known rpm to check OR known rpm_exists)
        (!exists_check || rpm_exists(rpm:exists_check)) &&
        rpm_check(sp:sp, cpu:_cpu, reference:reference, epoch:epoch, el_string:el_string, rpm_spec_vers_cmp:rpm_spec_vers_cmp, allowmaj:allowmaj, cves:cves)) flag++;
  }
}


if (flag)
{
  security_report_v4(
      port       : 0,
      severity   : SECURITY_WARNING,
      extra      : rpm_report_get()
  );
  exit(0);
}
else
{
  var tested = pkg_tests_get();
  if (tested) audit(AUDIT_PACKAGE_NOT_AFFECTED, tested);
  else audit(AUDIT_PACKAGE_NOT_INSTALLED, 'kernel');
}

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

28 Oct 2026 00:00Current
6.2Medium risk
Vulners AI Score6.2
CVSS 3.17.8
EPSS0.00123
3