Linux 커널에서는 다음 취약점이 해결되었습니다. af_unix: unix_stream_data_wait()에서 tail->len의 UAF 읽기 문제를 수정했습니다. unix_stream_data_wait()는 없이 skb_peek_tail(&sk->sk_receive_queue)을 수행합니다. 해당 대기열의 SKB가 대기열에서 제거되는 것을 방지하는 잠금을 보유하고 해방되었습니다. 이는 커밋 79f632c71bea("unix/stream: fix 대기열에 있는 데이터보다 큰 오프셋으로 엿보기"). 이것의 첫 번째 결과는 포인터 비교입니다. `tail != last`는 거짓일 수도 있습니다.
Linux 커널에서는 다음 취약점이 해결되었습니다.
af_unix: unix_stream_data_wait()에서 tail->len의 UAF 읽기 문제를 수정했습니다.
unix_stream_data_wait()는 없이 skb_peek_tail(&sk->sk_receive_queue)을 수행합니다.
해당 대기열의 SKB가 대기열에서 제거되는 것을 방지하는 잠금을 보유하고
해방되었습니다.
이는 커밋 79f632c71bea("unix/stream: fix
대기열에 있는 데이터보다 큰 오프셋으로 엿보기").
이것의 첫 번째 결과는 포인터 비교입니다.
tail != last는 last가 의미상으로 참조하더라도 false일 수 있습니다.
이미 해제된 SKB인 반면 'tail'은 동일한 주소에 할당된 새 SKB입니다.
이로 인해 unix_stream_data_wait()가 new 이후에 잘못 계속 차단될 수 있습니다.
데이터가 도착했지만, recv()와
동일한 소켓의 일반 recv()가 경주 중입니다. 이는 아마도
진짜 문제.
하지만 커밋 2b514574f7e8("net: af_unix: 스트림에 대한 스플라이스 구현
af_unix 소켓"), tail은 실제로 역참조되어 UAF가 발생할 수 있습니다.
다음 경쟁 시나리오(test_setup()이 단일 스레드로 실행되는 경우,
그 후에는 test_thread1()과 test_thread2()가 동시에 실행됩니다.
두 개의 스레드:
정적 int 양말[2];
무효 test_setup(void) {
소켓쌍(AF_UNIX, SOCK_STREAM, 0, 양말);
send(양말[1], "A", 1, 0);
int 엿보기 = 1;
setockopt(양말[0], SOL_SOCKET, SO_PEEK_OFF, &peekoff, sizeof(peekoff));
}
무효 test_thread1(void) {
숯 더미;
recv(양말[0], &dummy, 1, MSG_PEEK);
}
무효 test_thread2(void) {
숯 더미;
recv(양말[0], &dummy, 1, 0);
종료(양말[1], SHUT_WR);
}
다음과 같이 경주할 때:
스레드1 스레드2
unix_stream_read_generic
mutex_lock(&u->iolock)
skb_peek(&sk->sk_receive_queue)
skb_peek_next(skb, &sk->sk_receive_queue)
mutex_unlock(&u->iolock)
unix_stream_read_generic
unix_state_lock(sk)
skb_peek(&sk->sk_receive_queue)
unix_state_unlock(sk)
unix_stream_data_wait
unix_state_lock(sk)
tail = skb_peek_tail(&sk->sk_receive_queue)
spin_lock(&sk->sk_receive_queue.lock)
__skb_unlink(skb, &sk->sk_receive_queue)
spin_unlock(&sk->sk_receive_queue.lock)
Consume_skb(skb) [SKB를 해제합니다]
`tail != 마지막`: 거짓
`tail`: 참
`tail->len != last_len` ***UAF***
tail->len 읽기를 제거하여 UAF를 수정합니다. tail->len을 확인하면 UNIX 소켓의 수신 대기열에 있는 SKB가 커질 수 있는 경우에만 의미가 있습니다. 더 이상 일어날 수 없는 일입니다.
쿠니유키는 이렇게 설명했다.
커밋 869e7c62486e("net: af_unix: 스트림 sendpage 구현 support") sendpage() 지원이 추가되었으며, 데이터가 마지막 페이지에 추가될 수 있습니다. 수신자의 대기열에 있는 skb.
그래서 마지막 skb의 길이가 변경되었는지 확인해야 했습니다. unix_stream_data_wait()에서 새 데이터를 기다리는 동안.
그러나 a0dbf5f818f9("af_unix: Support MSG_SPLICE_PAGES")를 커밋하고 커밋 57d44a354a43 ("unix: unix_stream_sendpage()를 사용하도록 변환 MSG_SPLICE_PAGES") sendmsg()를 리팩터링했으며 이제 데이터가 항상 추가됩니다. 새로운 skb로.
즉, 이 수정 사항은 6.5 이전 커널에는 적합하지 않습니다.
왜 이 VPI인가 (설명가능 · 실험적)
VPI 산정 기준
| 영향도 | 88.00 |
| 악용 신호(추가 악용신호 없음) | ×1.00 |
| VPI | 88.00 |
VPI 공식 vpi-v1 기준