🔍 CVE-2025-22111

5.5
CVSS Score
MEDIUM
2025-04-16
2026-10-15 02:17
✅ 완료

🇰🇷 한글 설명

리눅스 커널의 네트워크 네임스페이스 관리 중 RTNL(Routing Netlink) 락을 해제하고 다시 획득하는 과정에서 레이스 컨디션(Race Condition)이 발생할 수 있는 취약점입니다. 브리지 장치에서 인터페이스를 제거하는 스레드와 브리지를 삭제하는 스레드가 동시에 실행될 경우, 참조 카운트 불일치로 인해 커널이 대기 상태에 빠지거나 시스템 로그에 오류(splat)가 발생할 수 있습니다.

💡 쉬운 설명

네트워크 설정을 변경하는 두 가지 작업이 동시에 일어날 때, 컴퓨터가 어떤 작업을 먼저 처리해야 할지 혼란을 겪어 시스템이 멈칫하거나 오류를 내뱉는 문제입니다. 이는 주로 네트워크 장치를 연결하거나 끊는 과정에서 발생합니다.

🇺🇸 원문 (English)

In the Linux kernel, the following vulnerability has been resolved: net: Remove RTNL dance for SIOCBRADDIF and SIOCBRDELIF. SIOCBRDELIF is passed to dev_ioctl() first and later forwarded to br_ioctl_call(), which causes unnecessary RTNL dance and the splat below [0] under RTNL pressure. Let's say Thread A is trying to detach a device from a bridge and Thread B is trying to remove the bridge. In dev_ioctl(), Thread A bumps the bridge device's refcnt by netdev_hold() and releases RTNL because the following br_ioctl_call() also re-acquires RTNL. In the race window, Thread B could acquire RTNL and try to remove the bridge device. Then, rtnl_unlock() by Thread B will release RTNL and wait for netdev_put() by Thread A. Thread A, however, must hold RTNL after the unlock in dev_ifsioc(), which may take long under RTNL pressure, resulting in the splat by Thread B. Thread A (SIOCBRDELIF) Thread B (SIOCBRDELBR) ---------------------- ---------------------- sock_ioctl sock_ioctl `- sock_do_ioctl `- br_ioctl_call `- dev_ioctl `- br_ioctl_stub |- rtnl_lock | |- dev_ifsioc ' ' |- dev = __dev_get_by_name(...) |- netdev_hold(dev, ...) . / |- rtnl_unlock ------. | | |- br_ioctl_call `---> |- rtnl_lock Race | | `- br_ioctl_stub |- br_del_bridge Window | | | |- dev = __dev_get_by_name(...) | | | May take long | `- br_dev_delete(dev, ...) | | | under RTNL pressure | `- unregister_netdevice_queue(dev, ...) | | | | `- rtnl_unlock \ | |- rtnl_lock <-' `- netdev_run_todo | |- ... `- netdev_run_todo | `- rtnl_unlock |- __rtnl_unlock | |- netdev_wait_allrefs_any |- netdev_put(dev, ...) <----------------' Wait refcnt decrement and log splat below To avoid blocking SIOCBRDELBR unnecessarily, let's not call dev_ioctl() for SIOCBRADDIF and SIOCBRDELIF. In the dev_ioctl() path, we do the following: 1. Copy struct ifreq by get_user_ifreq in sock_do_ioctl() 2. Check CAP_NET_ADMIN in dev_ioctl() 3. Call dev_load() in dev_ioctl() 4. Fetch the master dev from ifr.ifr_name in dev_ifsioc() 3. can be done by request_module() in br_ioctl_call(), so we move 1., 2., and 4. to br_ioctl_stub(). Note that 2. is also checked later in add_del_if(), but it's better performed before RTNL. SIOCBRADDIF and SIOCBRDELIF have been processed in dev_ioctl() since the pre-git era, and there seems to be no specific reason to process them there. [0]: unregister_netdevice: waiting for wpan3 to become free. Usage count = 2 ref_tracker: wpan3@ffff8880662d8608 has 1/1 users at __netdev_tracker_alloc include/linux/netdevice.h:4282 [inline] netdev_hold include/linux/netdevice.h:4311 [inline] dev_ifsioc+0xc6a/0x1160 net/core/dev_ioctl.c:624 dev_ioctl+0x255/0x10c0 net/core/dev_ioctl.c:826 sock_do_ioctl+0x1ca/0x260 net/socket.c:1213 sock_ioctl+0x23a/0x6c0 net/socket.c:1318 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:906 [inline] __se_sys_ioctl fs/ioctl.c:892 [inline] __x64_sys_ioctl+0x1a4/0x210 fs/ioctl.c:892 do_syscall_x64 arch/x86/entry/common.c:52 [inline] do_syscall_64+0xcb/0x250 arch/x86/entry/common.c:83 entry_SYSCALL_64_after_hwframe+0x77/0x7f

📍 영향받는 시스템

Linux Kernel (SIOCBRADDIF 및 SIOCBRDELIF 관련 ioctl 호출을 사용하는 시스템)

⚔️ 공격 벡터

로컬 권한을 가진 사용자가 네트워크 인터페이스 및 브리지 설정을 조작하는 ioctl 시스템 호출을 통해 레이스 컨디션을 유도할 수 있음

🛡️ 대응 방법

리눅스 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 RTNL 락 관리 로직을 수정해야 함

🔧 검증 코드

출력된 커널 버전을 확인하여 해당 취약점이 해결된 패치 버전인지 확인하십시오.

Shell / Script
uname -r

📊 CVSS Vector String

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

💻 영향받는 소프트웨어

Linux Kernel