🇰🇷 한글 설명
Linux 커널의 switchdev 블로킹 알림 체인에서 재귀적 알림이 발생할 수 있는 문제가 확인되었습니다. 브리지 드라이버가 SWITCHDEV_BRPORT_UNOFFLOADED 이벤트를 처리하는 과정에서 같은 세마포어를 두 번 획득하여 교착 상태 경고(lockdep)가 발생합니다. 이를 해결하기 위해 블로킹 체인을 raw 알림 체인으로 변환하고 RTNL 뮤텍스로 보호하도록 수정되었습니다.
💡 쉬운 설명
네트워크 스위치 기능을 담당하는 리눅스 커널 부분에서 같은 잠금을 중복으로 걸어 시스템이 멈출 수 있는 버그입니다. 커널 개발자들이 알림 처리 방식을 바꿔 이 문제를 고쳤습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
net: switchdev: Convert blocking notification chain to a raw one
A blocking notification chain uses a read-write semaphore to protect the
integrity of the chain. The semaphore is acquired for writing when
adding / removing notifiers to / from the chain and acquired for reading
when traversing the chain and informing notifiers about an event.
In case of the blocking switchdev notification chain, recursive
notifications are possible which leads to the semaphore being acquired
twice for reading and to lockdep warnings being generated [1].
Specifically, this can happen when the bridge driver processes a
SWITCHDEV_BRPORT_UNOFFLOADED event which causes it to emit notifications
about deferred events when calling switchdev_deferred_process().
Fix this by converting the notification chain to a raw notification
chain in a similar fashion to the netdev notification chain. Protect
the chain using the RTNL mutex by acquiring it when modifying the chain.
Events are always informed under the RTNL mutex, but add an assertion in
call_switchdev_blocking_notifiers() to make sure this is not violated in
the future.
Maintain the "blocking" prefix as events are always emitted from process
context and listeners are allowed to block.
[1]:
WARNING: possible recursive locking detected
6.14.0-rc4-custom-g079270089484 #1 Not tainted
--------------------------------------------
ip/52731 is trying to acquire lock:
ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0
but task is already holding lock:
ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0
----
lock((switchdev_blocking_notif_chain).rwsem);
lock((switchdev_blocking_notif_chain).rwsem);
*** DEADLOCK ***
May be due to missing lock nesting notation
3 locks held by ip/52731:
#0: ffffffff84f795b0 (rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x727/0x1dc0
#1: ffffffff8731f628 (&net->rtnl_mutex){+.+.}-{4:4}, at: rtnl_newlink+0x790/0x1dc0
#2: ffffffff850918d8 ((switchdev_blocking_notif_chain).rwsem){++++}-{4:4}, at: blocking_notifier_call_chain+0x58/0xa0
stack backtrace:
...
? __pfx_down_read+0x10/0x10
? __pfx_mark_lock+0x10/0x10
? __pfx_switchdev_port_attr_set_deferred+0x10/0x10
blocking_notifier_call_chain+0x58/0xa0
switchdev_port_attr_notify.constprop.0+0xb3/0x1b0
? __pfx_switchdev_port_attr_notify.constprop.0+0x10/0x10
? mark_held_locks+0x94/0xe0
? switchdev_deferred_process+0x11a/0x340
switchdev_port_attr_set_deferred+0x27/0xd0
switchdev_deferred_process+0x164/0x340
br_switchdev_port_unoffload+0xc8/0x100 [bridge]
br_switchdev_blocking_event+0x29f/0x580 [bridge]
notifier_call_chain+0xa2/0x440
blocking_notifier_call_chain+0x6e/0xa0
switchdev_bridge_port_unoffload+0xde/0x1a0
...
📍 영향받는 시스템
수정 이전의 Linux 커널 (switchdev 및 bridge 기능을 사용하는 시스템)
⚔️ 공격 벡터
로컬 권한이 있는 사용자가 브리지 포트 구성 변경을 유발해 교착 상태를 일으킬 수 있으며, 서비스 거부(DoS) 가능성이 있습니다.
🛡️ 대응 방법
배포판 벤더가 제공하는 최신 보안 업데이트 커널로 업그레이드하고 재부팅합니다.
🔧 검증 코드
출력된 커널 버전이 배포판 보안 권고에서 패치된 버전 이상인지 확인하고, 해당 패치 적용 여부는 배포판의 패키지 변경 로그(예: apt changelog linux-image-$(uname -r))로 교차 확인합니다.