Lucene search
K

Unity Linux 20.1070e Security Update: kernel (UTSA-2025-987032)

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

Linux kernel fix for fscrypt keyrings usage to prevent use after free and deadlock.

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

include('compat.inc');

if (description)
{
  script_id(268758);
  script_version("1.2");
  script_set_attribute(attribute:"plugin_modification_date", value:"2025/10/15");

  script_cve_id("CVE-2022-49899");

  script_name(english:"Unity Linux 20.1070e Security Update: kernel (UTSA-2025-987032)");

  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-2025-987032 advisory.

    In the Linux kernel, the following vulnerability has been resolved:

    fscrypt: stop using keyrings subsystem for fscrypt_master_key

    The approach of fs/crypto/ internally managing the fscrypt_master_key
    structs as the payloads of struct key objects contained in a
    struct key keyring has outlived its usefulness.  The original idea was
    to simplify the code by reusing code from the keyrings subsystem.
    However, several issues have arisen that can't easily be resolved:

    - When a master key struct is destroyed, blk_crypto_evict_key() must be
      called on any per-mode keys embedded in it.  (This started being the
      case when inline encryption support was added.)  Yet, the keyrings
      subsystem can arbitrarily delay the destruction of keys, even past the
      time the filesystem was unmounted.  Therefore, currently there is no
      easy way to call blk_crypto_evict_key() when a master key is
      destroyed.  Currently, this is worked around by holding an extra
      reference to the filesystem's request_queue(s).  But it was overlooked
      that the request_queue reference is *not* guaranteed to pin the
      corresponding blk_crypto_profile too; for device-mapper devices that
      support inline crypto, it doesn't.  This can cause a use-after-free.

    - When the last inode that was using an incompletely-removed master key
      is evicted, the master key removal is completed by removing the key
      struct from the keyring.  Currently this is done via key_invalidate().
      Yet, key_invalidate() takes the key semaphore.  This can deadlock when
      called from the shrinker, since in fscrypt_ioctl_add_key(), memory is
      allocated with GFP_KERNEL under the same semaphore.

    - More generally, the fact that the keyrings subsystem can arbitrarily
      delay the destruction of keys (via garbage collection delay, or via
      random processes getting temporary key references) is undesirable, as
      it means we can't strictly guarantee that all secrets are ever wiped.

    - Doing the master key lookups via the keyrings subsystem results in the
      key_permission LSM hook being called.  fscrypt doesn't want this, as
      all access control for encrypted files is designed to happen via the
      files themselves, like any other files.  The workaround which SELinux
      users are using is to change their SELinux policy to grant key search
      access to all domains.  This works, but it is an odd extra step that
      shouldn't really have to be done.

    The fix for all these issues is to change the implementation to what I
    should have done originally: don't use the keyrings subsystem to keep
    track of the filesystem's fscrypt_master_key structs.  Instead, just
    store them in a regular kernel data structure, and rework the reference
    counting, locking, and lifetime accordingly.  Retain support for
    RCU-mode key lookups by using a hash table.  Replace fscrypt_sb_free()
    with fscrypt_sb_delete(), which releases the keys synchronously and runs
    a bit earlier during unmount, so that block devices are still available.

    A side effect of this patch is that neither the master keys themselves
    nor the filesystem keyrings will be listed in /proc/keys anymore.
    (Master key users and the master key users keyrings will still be
    listed.)  However, this was mostly an implementation detail, and it was
    intended just for debugging purposes.  I don't know of anyone using it.

    This patch does *not* change how master key users (->mk_users) works;
    that still uses the keyrings subsystem.  That is still needed for key
    quotas, and changing that isn't necessary to solve the issues listed
    above.  If we decide to change that too, it would be a separate patch.

    I've marked this as fixing the original commit that added the fscrypt
    keyring, but as noted above the most important issue that this patch
    fixes wasn't introduced until the addition of inline encryption support.

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-2025-987032
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?a878064f");
  # https://lore.kernel.org/linux-cve-announce/2025050101-CVE-2022-49899-d331@gregkh
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?d55250d4");
  script_set_attribute(attribute:"see_also", value:"https://nvd.nist.gov/vuln/detail/CVE-2022-49899");
  script_set_attribute(attribute:"solution", value:
"Update the affected kernel package.");
  script_set_cvss_base_vector("CVSS2#AV:L/AC:L/Au:S/C:N/I:N/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:N/I:N/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-2022-49899");

  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:"2022/12/08");
  script_set_attribute(attribute:"patch_publication_date", value:"2025/09/23");
  script_set_attribute(attribute:"plugin_publication_date", value:"2025/10/07");

  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) 2025 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.1070e([^0-9]|$)", string:os_version)) audit(AUDIT_OS_NOT, 'UOS Server 20.1070e', '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 && 'x86_64' >!< cpu) audit(AUDIT_LOCAL_CHECKS_NOT_IMPLEMENTED, 'UOS Server', cpu);


var constraints = [
  {
    'release': '20',
    'sp': '1070e',
    'pkgs': [
      {'reference':'kernel-5.10.0-74.16', 'sp':'1070e', 'cpu':'aarch64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-5.10.0-74.16', 'sp':'1070e', 'cpu':'amd64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-5.10.0-74.16', 'sp':'1070e', '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

15 Oct 2025 00:00Current
5.4Medium risk
Vulners AI Score5.4
CVSS 3.15.5
EPSS0.00185
SSVC
3