🇰🇷 한글 설명
Linux 커널 ksmbd 모듈에서 연결 종료 시 다른 세션의 채널 목록에서 해당 연결의 채널을 제거하지 않는 문제가 해결되었습니다. 이로 인해 해제된 연결 구조체를 가리키는 stale 채널이 남아 use-after-free가 발생할 수 있었습니다. 수정으로 연결 종료 시 모든 세션에서 채널을 항상 제거합니다.
💡 쉬운 설명
SMB 파일 서버 기능에서 연결이 끊긴 뒤에도 남아 있던 잘못된 정보를 정리하지 못하는 결함입니다. 이 결함은 메모리 손상과 세션 누수를 일으킬 수 있어 수정이 필요합니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
ksmbd: remove stale channels from all sessions on teardown
ksmbd_sessions_deregister() removes a connection's channels from other
sessions' channel lists only while conn->binding is still set:
if (conn->binding) {
hash_for_each_safe(sessions_table, ...)
ksmbd_chann_del(conn, sess);
}
conn->binding is a transient flag: it is cleared once a binding
SESSION_SETUP completes, and also by a subsequent non-binding
SESSION_SETUP on the same connection (a reauthentication on a bound
channel, or a new SessionId==0 setup). A connection that has bound a
channel into another session's ksmbd_chann_list and then clears
conn->binding leaves that channel behind when it disconnects: the
channel, whose chann->conn points at the now freed struct ksmbd_conn,
stays on the owner session's list.
When the owning connection later tears down, the second loop
dereferences the stale channel:
xa_for_each(&sess->ksmbd_chann_list, chann_id, chann)
if (chann->conn != conn)
ksmbd_conn_set_exiting(chann->conn); /* freed */
which is a use-after-free write into the freed ksmbd_conn (the same
stale channel is also walked by show_proc_session() through /proc). The
session is leaked as well, because its channel list never empties.
Remove the conn->binding gate so a connection always removes its
channels from every session on teardown.
📍 영향받는 시스템
ksmbd 모듈을 포함한 Linux 커널 (수정 커밋 이전 버전, 정확한 버전 범위는 배포판 권고 확인 필요)
⚔️ 공격 벡터
인증된 SMB 클라이언트가 채널 바인딩 후 재인증 등을 반복해 stale 채널을 남긴 뒤 연결을 끊어 해제된 메모리를 건드리게 하는 방식으로 추정됨
🛡️ 대응 방법
배포판 벤더가 제공하는 최신 커널 업데이트를 적용하거나 해당 수정 커밋이 포함된 커널로 업그레이드하고, 필요하지 않으면 ksmbd 모듈을 비활성화합니다.
🔧 검증 코드
ksmbd 모듈이 로드되지 않았다면 영향이 없고, 로드되어 있다면 uname -r 결과의 커널 버전을 배포판 보안 권고와 대조해 패치 적용 여부를 확인합니다.
lsmod | grep ksmbd; uname -r