Lucene search
K

Unity Linux 20.1070e Security Update: kernel (UTSA-2026-005441)

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

Unity Linux 20.1070e kernel update fixes a bcache oversized read request in the cache miss path.

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

include('compat.inc');

if (description)
{
  script_id(300907);
  script_version("1.1");
  script_set_attribute(attribute:"plugin_modification_date", value:"2026/03/05");

  script_cve_id("CVE-2021-47275");

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

  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-005441 advisory.

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

    bcache: avoid oversized read request in cache missing code path

    In the cache missing code path of cached device, if a proper location
    from the internal B+ tree is matched for a cache miss range, function
    cached_dev_cache_miss() will be called in cache_lookup_fn() in the
    following code block,
    [code block 1]
      526         unsigned int sectors = KEY_INODE(k) == s->iop.inode
      527                 ? min_t(uint64_t, INT_MAX,
      528                         KEY_START(k) - bio->bi_iter.bi_sector)
      529                 : INT_MAX;
      530         int ret = s->d->cache_miss(b, s, bio, sectors);

    Here s->d->cache_miss() is the call backfunction pointer initialized as
    cached_dev_cache_miss(), the last parameter 'sectors' is an important
    hint to calculate the size of read request to backing device of the
    missing cache data.

    Current calculation in above code block may generate oversized value of
    'sectors', which consequently may trigger 2 different potential kernel
    panics by BUG() or BUG_ON() as listed below,

    1) BUG_ON() inside bch_btree_insert_key(),
    [code block 2]
       886         BUG_ON(b->ops->is_extents && !KEY_SIZE(k));
    2) BUG() inside biovec_slab(),
    [code block 3]
       51         default:
       52                 BUG();
       53                 return NULL;

    All the above panics are original from cached_dev_cache_miss() by the
    oversized parameter 'sectors'.

    Inside cached_dev_cache_miss(), parameter 'sectors' is used to calculate
    the size of data read from backing device for the cache missing. This
    size is stored in s->insert_bio_sectors by the following lines of code,
    [code block 4]
      909    s->insert_bio_sectors = min(sectors, bio_sectors(bio) + reada);

    Then the actual key inserting to the internal B+ tree is generated and
    stored in s->iop.replace_key by the following lines of code,
    [code block 5]
      911   s->iop.replace_key = KEY(s->iop.inode,
      912                    bio->bi_iter.bi_sector + s->insert_bio_sectors,
      913                    s->insert_bio_sectors);
    The oversized parameter 'sectors' may trigger panic 1) by BUG_ON() from
    the above code block.

    And the bio sending to backing device for the missing data is allocated
    with hint from s->insert_bio_sectors by the following lines of code,
    [code block 6]
      926    cache_bio = bio_alloc_bioset(GFP_NOWAIT,
      927                 DIV_ROUND_UP(s->insert_bio_sectors, PAGE_SECTORS),
      928                 &dc->disk.bio_split);
    The oversized parameter 'sectors' may trigger panic 2) by BUG() from the
    agove code block.

    Now let me explain how the panics happen with the oversized 'sectors'.
    In code block 5, replace_key is generated by macro KEY(). From the
    definition of macro KEY(),
    [code block 7]
      71 #define KEY(inode, offset, size)                                  \
      72 ((struct bkey) {                                                  \
      73      .high = (1ULL << 63) | ((__u64) (size) << 20) | (inode),     \
      74      .low = (offset)                                              \
      75 })

    Here 'size' is 16bits width embedded in 64bits member 'high' of struct
    bkey. But in code block 1, if KEY_START(k) - bio->bi_iter.bi_sector is
    very probably to be larger than (1<<16) - 1, which makes the bkey size
    calculation in code block 5 is overflowed. In one bug report the value
    of parameter 'sectors' is 131072 (= 1 << 17), the overflowed 'sectors'
    results the overflowed s->insert_bio_sectors in code block 4, then makes
    size field of s->iop.replace_key to be 0 in code block 5. Then the 0-
    sized s->iop.replace_key is inserted into the internal B+ tree as cache
    missing check key (a special key to detect and avoid a racing between
    normal write request and cache missing read request) as,
    [code block 8]
      915   ret = bch_btree_insert_check_key(b, &s->op, &s->iop.replace_key);

    Then the 0-sized s->iop.replace_key as 3rd parameter triggers the bkey
    size check BUG_ON() in code block 2, and causes the kernel panic 1).

    Another ke
    ---truncated---

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-005441
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?1b3cf56a");
  # https://lore.kernel.org/linux-cve-announce/2024052152-CVE-2021-47275-0e3d@gregkh
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?120d3046");
  script_set_attribute(attribute:"see_also", value:"https://nvd.nist.gov/vuln/detail/CVE-2021-47275");
  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-2021-47275");

  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:"2024/05/21");
  script_set_attribute(attribute:"patch_publication_date", value:"2026/03/02");
  script_set_attribute(attribute:"plugin_publication_date", value:"2026/03/05");

  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.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 && 'sw_64' >!< 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-79.7', 'sp':'1070e', 'cpu':'aarch64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-5.10.0-79.7', 'sp':'1070e', 'cpu':'amd64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-5.10.0-79.7', 'sp':'1070e', 'cpu':'sw_64', 'rpm_spec_vers_cmp':TRUE},
      {'reference':'kernel-5.10.0-79.7', '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

05 Mar 2026 00:00Current
5.9Medium risk
Vulners AI Score5.9
CVSS 3.15.5
EPSS0.00196
SSVC
3