LinuxのLinux KernelにおけるNULL ポインタデリファレンスに関する脆弱性
タイトル LinuxのLinux KernelにおけるNULL ポインタデリファレンスに関する脆弱性
概要

Linuxカーネルにおいて、以下の脆弱性が修正されました。net/schedのtaprioにおけるクラスダンプ時のNULLポインタ逆参照の問題を修正しました。TAPRIOの子qdiscがRTM_DELQDISC経由で削除されると、taprio_graft()がnew == NULLの状態で呼ばれ、NULLをq-qdiscs[cl - 1]に格納します。その後のRTM_GETTCLASSのダンプ操作はtaprio_walk()で全クラスを巡回し、taprio_dump_class()を呼び出します。この過程でtaprio_leaf()がNULLポインタを返し、その逆参照によりchild-handleを読み取ろうとし、カーネルのNULLポインタ逆参照が発生してしまいます。このバグはCONFIG_NET_SCH_TAPRIOが有効な任意のカーネルで、namespaceスコープのCAP_NET_ADMIN権限を持つ場合に発生します。特権のないユーザー名前空間が有効なシステムでは、特権のないローカルユーザーが新しいネットワーク名前空間内でtaprio qdiscを作成し、明示的な子qdiscをグラフトし、それを削除し、クラスダンプを要求することでカーネルパニックを引き起こせます。RTM_GETTCLASSダンプ自体は権限を必要としません。修正はtaprio_graft()内でnewがNULLのときに&noop_qdiscに置換する方法で行われました。これはmultiq_graft()など他のqdiscでも用いられる共通のパターンであり、q-qdiscs[]スロットがNULLにならないようにするためのものです。この修正により、コントロールプレーンダンプパスが個別のNULLチェックを不要とし、安全に動作します。データプレーンパス(taprio_enqueueおよびtaprio_dequeue_from_txq)には以前より明示的なNULLガードがあり、パケットを正常に破棄またはスキップしていましたが、これらのチェックは&noop_qdiscのテストに更新されました。この更新がない場合、パケットはtaprio_enqueue_one()に到達し、ルートqdiscのqlenとbacklogが増加し、子のenqueueを呼び出します。noop_qdiscはパケットを破棄しますが、これらのカウンタはロールバックされず、ルートqdiscの統計が永久に膨張してしまいます。この変更後は*oldが有効なqdisc、NULL、または&noop_qdiscのいずれかとなり、qdisc_put(*old)は最初の場合にのみ呼び出し、増加していないnoop_qdiscのリファレンスカウントを減少させないようにしています。

想定される影響 ・当該ソフトウェアが扱う情報について、外部への漏えいは発生しません。 ・当該ソフトウェアが扱う情報について、書き換えは発生しません。 ・当該ソフトウェアが完全に停止する可能性があります。 
対策

リリース情報、またはパッチ情報が公開されています。参考情報を参照して適切な対策を実施してください。

公表日 2026年5月27日0:00
登録日 2026年6月29日11:17
最終更新日 2026年6月29日11:17
CVSS3.0 : 警告
スコア 5.5
ベクター CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:N/A:H
影響を受けるシステム
Linux
Linux Kernel 6.13 以上 6.18.33 未満
Linux Kernel 6.19 以上 7.0.10 未満
Linux Kernel 6.6 以上 6.6.141 未満
Linux Kernel 6.7 以上 6.12.91 未満
Linux Kernel 7.1
CVE (情報セキュリティ 共通脆弱性識別子)
CWE (共通脆弱性タイプ一覧)
その他
変更履歴
No 変更内容 変更日
1 [2026年06月29日]
  掲載
2026年6月29日11:17

NVD脆弱性情報
CVE-2026-45845
概要

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

net/sched: taprio: fix NULL pointer dereference in class dump

When a TAPRIO child qdisc is deleted via RTM_DELQDISC, taprio_graft()
is called with new == NULL and stores NULL into q->qdiscs[cl - 1].
Subsequent RTM_GETTCLASS dump operations walk all classes via
taprio_walk() and call taprio_dump_class(), which calls taprio_leaf()
returning the NULL pointer, then dereferences it to read child->handle,
causing a kernel NULL pointer dereference.

The bug is reachable with namespace-scoped CAP_NET_ADMIN on any kernel
with CONFIG_NET_SCH_TAPRIO enabled. On systems with unprivileged user
namespaces enabled, an unprivileged local user can trigger a kernel
panic by creating a taprio qdisc inside a new network namespace,
grafting an explicit child qdisc, deleting it, and requesting a class
dump. The RTM_GETTCLASS dump itself requires no capability.

Oops: general protection fault, probably for non-canonical address 0xdffffc0000000007: 0000 [#1] SMP KASAN NOPTI
KASAN: null-ptr-deref in range [0x0000000000000038-0x000000000000003f]
RIP: 0010:taprio_dump_class (net/sched/sch_taprio.c:2478)
Call Trace:
<TASK>
tc_fill_tclass (net/sched/sch_api.c:1966)
qdisc_class_dump (net/sched/sch_api.c:2326)
taprio_walk (net/sched/sch_taprio.c:2514)
tc_dump_tclass_qdisc (net/sched/sch_api.c:2352)
tc_dump_tclass_root (net/sched/sch_api.c:2370)
tc_dump_tclass (net/sched/sch_api.c:2431)
rtnl_dumpit (net/core/rtnetlink.c:6864)
netlink_dump (net/netlink/af_netlink.c:2325)
rtnetlink_rcv_msg (net/core/rtnetlink.c:6959)
netlink_rcv_skb (net/netlink/af_netlink.c:2550)
</TASK>

Fix this by substituting &noop_qdisc when new is NULL in
taprio_graft(), a common pattern used by other qdiscs (e.g.,
multiq_graft()) to ensure the q->qdiscs[] slots are never NULL.
This makes control-plane dump paths safe without requiring individual
NULL checks.

Since the data-plane paths (taprio_enqueue and taprio_dequeue_from_txq)
previously had explicit NULL guards that would drop/skip the packet
cleanly, update those checks to test for &noop_qdisc instead. Without
this, packets would reach taprio_enqueue_one() which increments the root
qdisc's qlen and backlog before calling the child's enqueue; noop_qdisc
drops the packet but those counters are never rolled back, permanently
inflating the root qdisc's statistics.

After this change *old can be a valid qdisc, NULL, or &noop_qdisc.
Only call qdisc_put(*old) in the first case to avoid decreasing
noop_qdisc's refcount, which was never increased.

公表日 2026年5月27日20:16
登録日 2026年5月28日4:10
最終更新日 2026年5月27日23:48
関連情報、対策とツール
共通脆弱性一覧