Lucene search
+L

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

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

Out-of-bounds read in Linux kernel IB/isert handlers allows for information disclosure.

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

include('compat.inc');

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

  script_cve_id("CVE-2026-90414");

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

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

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

    IB/isert: reject PDUs declaring more data than was received

    isert_recv_done() hands each received PDU to the opcode handlers without
    ever looking at wc->byte_len, the number of bytes the HCA actually placed
    in the receive descriptor. The handlers then copy that many bytes - the
    data-segment length the initiator declared in the BHS
    (ntoh24(hdr->dlength), via the derived unsol_data_len / imm_data_len) -
    out of the fixed-size descriptor:

      isert_handle_iscsi_dataout():
            sg_copy_from_buffer(sg_start, sg_nents, isert_get_data(rx_desc),
                                unsol_data_len);
      isert_handle_scsi_cmd():
            sg_copy_from_buffer(cmd->se_cmd.t_data_sg, sg_nents,
                                isert_get_data(rx_desc), imm_data_len);

    Because the declared length is never checked against wc->byte_len, an
    initiator can declare a data segment larger than the bytes it actually
    sent (and larger than the descriptor) and cause an out-of-bounds read of
    the receive buffer.

    Nothing upstream of isert closes this door:

      - __iscsit_check_dataout_hdr() bounds the inbound payload against
        conn_ops->MaxXmitDataSegmentLength (MXDSL) - a transmit parameter,
        used here for the inbound check.
      - iscsi_set_connection_parameters() sets
        ops->MaxXmitDataSegmentLength = ops->TargetRecvDataSegmentLength;
        and TARGETRECVDATASEGMENTLENGTH is absent from the min()-clamp list in
        iscsi_check_acceptor_state(), so the value the initiator declares is
        adopted verbatim (type range 512..16777215). The initiator effectively
        raises its own ceiling.
      - isert never clamps the negotiated value to its own fixed receive
        descriptor (ISER_RX_SIZE, 9216 bytes), so the target core's bound and
        the descriptor size are unrelated.

    The imm_data_len == data_len path is more than an over-read: it aliases
    the receive descriptor via sg_set_buf() and passes it to the backend as
    the data source for the SCSI WRITE, so an over-declared length causes heap
    contents past the descriptor to be written through the backend to the
    backing store. The backend is the victim of the oversized scatterlist
    isert hands it, not the cause; no read-back of the written bytes was
    demonstrated.

    Trigger: after login completes (full feature phase), an initiator that has
    declared a large TargetRecvDataSegmentLength and a FirstBurstLength that
    permits unsolicited/immediate data sends a PDU whose declared data-segment
    length exceeds what was received. With KASAN:

      BUG: KASAN: slab-out-of-bounds in sg_copy_buffer+0x150/0x1c0
      Read of size 4096 at addr ffff888109720800 by task kworker/1:0H/25
      Workqueue: ib-comp-wq ib_cq_poll_work
      Call Trace:
       sg_copy_buffer+0x150/0x1c0
       isert_recv_done+0xba6/0x2390
       __ib_process_cq+0xe1/0x390
       ib_cq_poll_work+0x46/0x150

    isert_recv_done+0xba6 resolves to isert_handle_iscsi_dataout()
    (ib_isert.c:1160), inlined through isert_rx_opcode().

    Validate wc->byte_len against the framing in isert_recv_done() before the
    PDU reaches any handler, and reinstate the connection if it is short.
    Because the test compares without subtracting the header length, it also
    rejects PDUs shorter than the iSER and iSCSI headers, which would otherwise
    be parsed out of stale descriptor contents. The login handler rejects PDUs
    shorter than ISER_HEADERS_LEN (commit 29e7b925ae6d (IB/isert: Reject login
    PDUs shorter than ISER_HEADERS_LEN)) but does not bound the declared
    length either; that is fixed in the next patch. The data handlers had no
    length check at all.

    isert reads the data segment from a fixed offset: isert_get_data()
    returns the iSER header plus ISER_HEADERS_LEN and makes no adjustment for
    an AHS.  The bytes the handlers touch are therefore exactly
    [ISER_HEADERS_LEN, ISER_HEADERS_LEN + dlength), and comparing that sum
    against wc->byte_len bounds precisely the region that is read.  An AHS
    term would only make the test stricter without bounding anything furth
    ---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-146682
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?a4ea7d42");
  # https://lore.kernel.org/linux-cve-announce/2026091717-CVE-2026-90414-49a5@gregkh
  script_set_attribute(attribute:"see_also", value:"http://www.nessus.org/u?add8de8b");
  script_set_attribute(attribute:"see_also", value:"https://nvd.nist.gov/vuln/detail/CVE-2026-90414");
  script_set_attribute(attribute:"solution", value:
"Update the affected kernel package.");
  script_set_cvss_base_vector("CVSS2#AV:N/AC:L/Au:N/C:C/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:N/AC:L/PR:N/UI:N/S:U/C:H/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-2026-90414");

  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/17");
  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_HOLE,
      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
7.2High risk
Vulners AI Score7.2
CVSS 3.19.1
EPSS0.00514
2