🇰🇷 한글 설명
Linux 커널 usbnet 드라이버에서 USB 이더넷 장치 연결 해제(disconnect) 시 linkwatch 작업과 관련된 use-after-free 취약점이 발생한다. usbnet_deferred_kevent() 대기가 ->ndo_stop()이 아닌 ->disconnect()에서 이루어져, 해제된 netdev에 대해 링크 상태 작업이 실행될 수 있다. 이 문제는 aqc111, asix, ax88179_178a, ch9200, smsc75xx 드라이버에 영향을 준다.
💡 쉬운 설명
USB 이더넷 장치를 뽑는 순간 시스템이 이미 해제된 네트워크 정보에 접근하면서 오류가 날 수 있습니다. 이로 인해 시스템 불안정이나 권한 상승 가능성이 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
usbnet: Fix linkwatch use-after-free on disconnect
usbnet uses the work usbnet_deferred_kevent() to perform tasks which may
sleep. On disconnect, completion of the work was originally awaited in
->ndo_stop(). But in 2003, that was moved to ->disconnect() by historic
commit "[PATCH] USB: usbnet, prevent exotic rtnl deadlock":
https://git.kernel.org/tglx/history/c/0f138bbfd83c
The change was made because back then, the kernel's workqueue
implementation did not allow waiting for a single work. One had to wait
for completion of *all* work by calling flush_scheduled_work(), and that
could deadlock when waiting for usbnet_deferred_kevent() with rtnl_mutex
held in ->ndo_stop().
The commit solved one problem but created another: It causes a
use-after-free in USB Ethernet drivers aqc111.c, asix_devices.c,
ax88179_178a.c, ch9200.c and smsc75xx.c:
* If the drivers receive a link change interrupt immediately before
disconnect, they raise EVENT_LINK_RESET in their (non-sleepable)
->status() callback and schedule usbnet_deferred_kevent().
* usbnet_deferred_kevent() invokes the driver's ->link_reset() callback,
which calls netif_carrier_{on,off}().
* That in turn schedules the work linkwatch_event().
Because usbnet_deferred_kevent() is awaited after unregister_netdev(),
netif_carrier_{on,off}() may operate on an unregistered netdev and
linkwatch_event() may run after free_netdev(), causing a use-after-free.
In 2010, usbnet was changed to only wait for a single instance of
usbnet_deferred_kevent() instead of *all* work by commit 23f333a2bfaf
("drivers/net: don't use flush_scheduled_work()").
Unfortunately the commit neglected to move the wait back to
->ndo_stop(). Rectify that omission at long last.
📍 영향받는 시스템
Linux 커널(해당 수정 이전 버전)의 usbnet 기반 USB 이더넷 드라이버 사용 시스템
⚔️ 공격 벡터
물리적으로 USB 이더넷 장치를 연결 해제하는 시점에 링크 변경 인터럽트를 유발하여 해제된 메모리를 접근하게 하는 방식
🛡️ 대응 방법
해당 패치가 포함된 최신 Linux 커널로 업데이트하거나 배포판의 보안 업데이트를 적용한다.
🔧 검증 코드
출력된 커널 버전을 확인하여 해당 CVE 수정이 포함된 안정 버전(배포판 보안 공지 기준)보다 이전이면 취약 가능성이 있으며, 배포판 패키지 변경 로그에서 CVE-2022-50220 수정 여부를 함께 확인한다.