---
id: CVE-2026-98811
title: 'net/sched: cls_api: reclaim an empty proto on the error path'
summary: |-
  In the Linux kernel, the following vulnerability has been resolved:

  net/sched: cls_api: reclaim an empty proto on the error path

  Two racing tc filter add requests on the same chain/prio of an
  unlocked classifier both run change() on th…
severity: none
vendor: Linux
product: Linux
affected:
  - >-
    Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 <
    315e4fe65cf02ef052de5e6298c3088e448b7517
  - >-
    Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 <
    ebc9611ab154c0cd9f1320e2a73f5e936d7535a9
  - >-
    Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 <
    570141625d212fbbcffb9665cb45c0f04610e61a
  - >-
    Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 <
    0bb8eab29b55045281a4963d4557f2776cdf8cfa
  - Linux 5.1
published: '2026-10-18'
updated: '2026-10-18'
sourceUpdated: '2026-10-18T15:48:57.588Z'
source: CVEORG
sourceUrl: 'https://www.cve.org/CVERecord?id=CVE-2026-98811'
references:
  - url: 'https://git.kernel.org/stable/c/315e4fe65cf02ef052de5e6298c3088e448b7517'
  - url: 'https://git.kernel.org/stable/c/ebc9611ab154c0cd9f1320e2a73f5e936d7535a9'
  - url: 'https://git.kernel.org/stable/c/570141625d212fbbcffb9665cb45c0f04610e61a'
  - url: 'https://git.kernel.org/stable/c/0bb8eab29b55045281a4963d4557f2776cdf8cfa'
tags:
  - cve.org
ingestedAt: '2026-10-18T16:47:32.478Z'
---

## Overview

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

net/sched: cls_api: reclaim an empty proto on the error path

Two racing tc filter add requests on the same chain/prio of an
unlocked classifier both run change() on the shared proto and both
can fail: the winner's tcf_chain_tp_delete_empty() attempt gives up
because the loser's handle is still in the idr, and the loser's
error path drops only its own reference without a second reclamation
attempt. The empty proto stays linked in the chain, holding the
chain reference, a block reference and the classifier module
reference until the chain or block is torn down.

Reclaim the proto on the error path of any failed request that holds
a proto reference. The reclamation is emptiness-gated:
tcf_chain_tp_delete_empty() unlinks the proto only when
delete_empty() admits it is empty, so a live shared proto is never
unlinked. A proto the request created is reclaimed unconditionally -
it is the only owner, so marking it for deletion is safe even without
a delete_empty callback. Classifiers without one (the check marks the
proto unconditionally) are rtnl-serialized, so the raced window this
guard closes cannot arise for them.

This is a follow-up to commit d4e359b3608a ("net/sched: cls_api: fix
teardown of an adopted proto on insert-race loss"), which stopped the
loser of the insert race from unlinking the winner's live proto but
left the empty-proto residual in place.

Conditions to recreate:
- CONFIG_NET_CLS_FLOWER=y; veth pair
- tc qdisc add dev veth0 ingress
- two concurrent `tc filter add dev veth0 ingress protocol ip pref 1
  flower skip_sw ... action drop` (both fail in fl_hw_replace_filter
  after publishing their handle in the idr); repeat in a loop
- an empty flower tp stays linked after both requests fail; visible
  as a bare `filter protocol ip pref 1 flower chain 0` header in
  `tc filter show` with no filter entries
- CAP_NET_ADMIN (namespace-local via unshare -Urn suffices)

## Affected

- `Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 < 315e4fe65cf02ef052de5e6298c3088e448b7517`
- `Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 < ebc9611ab154c0cd9f1320e2a73f5e936d7535a9`
- `Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 < 570141625d212fbbcffb9665cb45c0f04610e61a`
- `Linux >= 8b64678e0af8f4d62a40149baedebe78503a5255 < 0bb8eab29b55045281a4963d4557f2776cdf8cfa`
- `Linux 5.1`

## Remediation

Refer to the linked advisories for vendor-supplied fixes and affected version ranges.
