TencentOS Server 4: kernel (TSSA-2026:0792)

high Nessus Plugin ID 333128

Synopsis

The remote TencentOS Server 4 host is missing one or more security updates.

Description

The version of Tencent Linux installed on the remote TencentOS Server 4 host is prior to tested version. It is, therefore, affected by multiple vulnerabilities as referenced in the TSSA-2026:0792 advisory.

Package updates are available for TencentOS Server 4 that fix the following vulnerabilities:

CVE-2026-31502:
In the Linux kernel, the following vulnerability has been resolved: xfs: resample the data fork mapping after cycling ILOCK. xfs_reflink_fill_{cow_hole,delalloc} are both presented with an inode, a data fork mapping, and a cow fork mapping. Unfortunately, these two helpers cycle the ILOCK to grab a transaction, which means that the mappings are stale as soon as we reacquire the ILOCK. Currently we refresh the cow fork mapping by re-calling xfs_find_trim_cow_extent, but we don't refresh the data fork mapping beforehand, which means that the xfs_bmap_trim_cow in that function queries the refcount btree about the wrong physical blocks and returns an inaccurate value in *shared. If *shared is now false, the directio write proceeds with a stale data fork mapping. Fix this by querying the data fork mapping if the sequence counter changes across the ILOCK cycle.

CVE-2026-53362:
In the Linux kernel, the following vulnerability has been resolved:

eventpoll: fix ep_remove struct eventpoll / struct file UAF

ep_remove() (via ep_remove_file()) cleared file->f_ep under file->f_lock but then kept using @file inside the critical section (is_file_epoll(), hlist_del_rcu() through the head, spin_unlock).
A concurrent __fput() taking the eventpoll_release() fastpath in that window observed the transient NULL, skipped eventpoll_release_file() and ran to f_op->release / file_free().

For the epoll-watches-epoll case, f_op->release is ep_eventpoll_release() -> ep_clear_and_put() -> ep_free(), which kfree()s the watched struct eventpoll. Its embedded ->refs hlist_head is exactly where epi->fllink.pprev points, so the subsequent hlist_del_rcu()'s *pprev = next scribbles into freed kmalloc-192 memory.

In addition, struct file is SLAB_TYPESAFE_BY_RCU, so the slot backing @file could be recycled by alloc_empty_file() -- reinitializing f_lock and f_ep -- while ep_remove() is still nominally inside that lock. The upshot is an attacker-controllable kmem_cache_free() against the wrong slab cache.

Pin @file via epi_fget() at the top of ep_remove() and gate the critical section on the pin succeeding. With the pin held @file cannot reach refcount zero, which holds __fput() off and transitively keeps the watched struct eventpoll alive across the hlist_del_rcu() and the f_lock use, closing both UAFs.

If the pin fails @file has already reached refcount zero and its
__fput() is in flight. Because we bailed before clearing f_ep, that path takes the eventpoll_release() slow path into eventpoll_release_file() and blocks on ep->mtx until the waiter side's ep_clear_and_put() drops it. The bailed epi's share of ep->refcount stays intact, so the trailing ep_refcount_dec_and_test() in ep_clear_and_put() cannot free the eventpoll out from under eventpoll_release_file(); the orphaned epi is then cleaned up there.

A successful pin also proves we are not racing eventpoll_release_file() on this epi, so drop the now-redundant re-check of epi->dying under f_lock. The cheap lockless READ_ONCE(epi->dying) fast-path bailout stays.

CVE-2026-43456:
In the Linux kernel, the following vulnerability has been resolved:

ipv6: account for fraggap on the paged allocation path

In __ip6_append_data(), when the paged-allocation branch is taken (MSG_MORE / NETIF_F_SG / large fraglen), alloclen and pagedlen are computed as

alloclen = fragheaderlen + transhdrlen;
pagedlen = datalen - transhdrlen;

datalen already includes fraggap (datalen = length + fraggap). When fraggap is non-zero, this is not the first skb and transhdrlen is zero.
The fraggap bytes carried over from the previous skb are copied just past the fragment headers in the new skb's linear area. The linear area is therefore undersized by fraggap bytes while pagedlen is overstated by the same amount, and the copy writes past skb->end into the trailing skb_shared_info.

An unprivileged user can trigger this via a UDPv6 socket using MSG_MORE together with MSG_SPLICE_PAGES.

The bad accounting was introduced by commit 773ba4fe9104 (ipv6:
avoid partial copy for zc). Before commit ce650a166335 (udp6: Fix
__ip6_append_data()'s handling of MSG_SPLICE_PAGES), the negative copy value caused -EINVAL to be returned. That later commit allowed MSG_SPLICE_PAGES to proceed in this case, making the corruption triggerable.

The non-paged branch sets alloclen to fraglen, which already accounts for fraggap because datalen does. Bring the paged branch in line by adding fraggap to alloclen and subtracting it from pagedlen.

After this adjustment, copy no longer collapses to -fraggap on the paged path, so remove the stale comment describing that old arithmetic.
Since a negative copy is no longer expected for a valid MSG_SPLICE_PAGES case, remove the MSG_SPLICE_PAGES exception from the negative copy check.

CVE-2026-46242:
In the Linux kernel, the following vulnerability has been resolved:

bonding: fix type confusion in bond_setup_by_slave()

kernel BUG at net/core/skbuff.c:2306! Oops: invalid opcode: 0000 [#1] SMP KASAN NOPTI RIP: 0010:pskb_expand_head+0xa08/0xfe0 net/core/skbuff.c:2306 RSP: 0018:ffffc90004aff760 EFLAGS: 00010293 RAX: 0000000000000000 RBX: ffff88807e3c8780 RCX: ffffffff89593e0e RDX: ffff88807b7c4900 RSI: ffffffff89594747 RDI: ffff88807b7c4900 RBP: 0000000000000820 R08: 0000000000000005 R09: 0000000000000000 R10: 00000000961a63e0 R11: 0000000000000000 R12: ffff88807e3c8780 R13: 00000000961a6560 R14: dffffc0000000000 R15: 00000000961a63e0 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007fe1a0ed8df0 CR3: 000000002d816000 CR4: 00000000003526f0 Call Trace:
<TASK> ipgre_header+0xdd/0x540 net/ipv4/ip_gre.c:900 dev_hard_header include/linux/netdevice.h:3439 [inline] packet_snd net/packet/af_packet.c:3028 [inline] packet_sendmsg+0x3ae5/0x53c0 net/packet/af_packet.c:3108 sock_sendmsg_nosec net/socket.c:727 [inline]
__sock_sendmsg net/socket.c:742 [inline]
____sys_sendmsg+0xa54/0xc30 net/socket.c:2592
___sys_sendmsg+0x190/0x1e0 net/socket.c:2646
__sys_sendmsg+0x170/0x220 net/socket.c:2678 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0x106/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7fe1a0e6c1a9

When a non-Ethernet device (e.g. GRE tunnel) is enslaved to a bond, bond_setup_by_slave() directly copies the slave's header_ops to the bond device:

bond_dev->header_ops = slave_dev->header_ops;

This causes a type confusion when dev_hard_header() is later called on the bond device. Functions like ipgre_header(), ip6gre_header(),all use netdev_priv(dev) to access their device-specific private data. When called with the bond device, netdev_priv() returns the bond's private data (struct bonding) instead of the expected type (e.g. struct ip_tunnel), leading to garbage values being read and kernel crashes.

Fix this by introducing bond_header_ops with wrapper functions that delegate to the active slave's header_ops using the slave's own device. This ensures netdev_priv() in the slave's header functions always receives the correct device.

The fix is placed in the bonding driver rather than individual device drivers, as the root cause is bond blindly inheriting header_ops from the slave without considering that these callbacks expect a specific netdev_priv() layout.

The type confusion can be observed by adding a printk in ipgre_header() and running the following commands:

ip link add dummy0 type dummy ip addr add 10.0.0.1/24 dev dummy0 ip link set dummy0 up ip link add gre1 type gre local 10.0.0.1 ip link add bond1 type bond mode active-backup ip link set gre1 master bond1 ip link set gre1 up ip link set bond1 up ip addr add fe80::1/64 dev bond1

CVE-2026-23451:
In the Linux kernel, the following vulnerability has been resolved:

team: fix header_ops type confusion with non-Ethernet ports

Similar to commit 950803f72547 (bonding: fix type confusion in bond_setup_by_slave()) team has the same class of header_ops type confusion.

For non-Ethernet ports, team_setup_by_port() copies port_dev->header_ops directly. When the team device later calls dev_hard_header() or dev_parse_header(), these callbacks can run with the team net_device instead of the real lower device, so netdev_priv(dev) is interpreted as the wrong private type and can crash.

The syzbot report shows a crash in bond_header_create(), but the root cause is in team: the topology is gre -> bond -> team, and team calls the inherited header_ops with its own net_device instead of the lower device, so bond_header_create() receives a team device and interprets netdev_priv() as bonding private data, causing a type confusion crash.

Fix this by introducing team header_ops wrappers for create/parse, selecting a team port under RCU, and calling the lower device callbacks with port->dev, so each callback always sees the correct net_device context.

Also pass the selected lower device to the lower parse callback, so recursion is bounded in stacked non-Ethernet topologies and parse callbacks always run with the correct device context.

CVE-2026-64600:
In the Linux kernel, the following vulnerability has been resolved:

bonding: prevent potential infinite loop in bond_header_parse()

bond_header_parse() can loop if a stack of two bonding devices is setup, because skb->dev always points to the hierarchy top.

Add new const struct net_device *dev parameter to (struct header_ops)->parse() method to make sure the recursion is bounded, and that the final leaf parse method is called.

CVE-2026-64531:
In the Linux kernel, the following vulnerability has been resolved: net: openvswitch: reject oversized nested action attrs. Open vSwitch stores generated flow actions as nlattrs, whose nla_len field is u16. An oversized generated container can be closed with a truncated nla_len, causing later dump or teardown to walk a structurally different stream than the one that was validated. An oversized nested CLONE/CT action may cause subsequent bytes to be interpreted as independent actions.

CVE-2026-64564:
In the Linux kernel, the following vulnerability has been resolved: sctp: don't free the ASCONF's own transport in DEL-IP processing. sctp_process_asconf() caches the transport the ASCONF chunk is processed against in asconf->transport. For an ASCONF located through its Address Parameter, that cached transport corresponds to the Address Parameter, which need not be the packet's source address. A single ASCONF can carry DEL-IP for the cached transport followed by a wildcard DEL-IP, causing use-after-free of the freed transport.

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

Note that Nessus has not tested for these issues but has instead relied only on the application's self-reported version number.

Solution

Update the affected packages.

See Also

https://mirrors.tencent.com/tlinux/errata/tssa-20260792.xml

Plugin Details

Severity: High

ID: 333128

File Name: tencentos_TSSA_2026_0792.nasl

Version: 1.1

Type: Local

Published: 8/6/2026

Updated: 8/6/2026

Supported Sensors: Nessus

Risk Information

VPR

Risk Factor: High

Score: 7.9

Percentile: 99.35

CVSS v2

Risk Factor: High

Base Score: 7.2

Temporal Score: 5.6

Vector: CVSS2#AV:L/AC:L/Au:N/C:C/I:C/A:C

CVSS Score Source: CVE-2026-64564

CVSS v3

Risk Factor: High

Base Score: 7.8

Temporal Score: 7

Vector: CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Temporal Vector: CVSS:3.0/E:P/RL:O/RC:C

CVSS Score Source: CVE-2026-64600

Vulnerability Information

CPE: cpe:/o:tencent:tencentos_server:4, p-cpe:/a:tencent:tencentos_server:kernel

Required KB Items: Host/local_checks_enabled, Host/etc/os-release, Host/TencentOS/rpm-list, Host/cpu

Exploit Available: true

Exploit Ease: Exploits are available

Patch Publication Date: 8/4/2026

Vulnerability Publication Date: 4/3/2026

Reference Information

CVE: CVE-2026-23451, CVE-2026-31502, CVE-2026-43456, CVE-2026-46242, CVE-2026-53362, CVE-2026-64531, CVE-2026-64564, CVE-2026-64600