В ядре Linux устранена следующая уязвимость:
sctp: удалить чанк, если его транспорт был удален
sctp_rcv() разрешает транспортировку один раз для каждого пакета и оставляет его в
чанк->транспорт. Ссылка поиска или та, которую принимает sctp_add_backlog().
если сокет принадлежит пользовательскому пространству, сохраняет его до тех пор, пока чанк не будет
были обработаны. Аутентифицированный ASCONF DEL-IP тем временем может удалить его.
sctp_assoc_rm_peer() выводит транспорт из ассоциации и вызывает
sctp_transport_free(), который помечает его как мертвый и удаляет ссылку
проведено объединение.
На обоих путях есть окно: пакет может сидеть на
невыполненная работа сокета, а на прямом пути поиск завершается раньше
bh_lock_sock(). Часть DATA в этом пакете возвращает удаленный транспорт обратно в
asoc->peer.last_data_from. Как только пакет будет готов, эта ссылка будет
и транспорт освобождается RCU, поэтому следующий задержанный SACK переносит
указатель на чанк SACK, а sctp_outq_select_transport() считывает
освобожденное состояние транспорта.
Отбросьте чанк в sctp_inq_push() рядом с существующей проверкой rcvr->dead. Оба пути достигают его с удержанной блокировкой сокета ассоциации. Партнер
ретранслирует его.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: sctp: drop a chunk if its transport was removed sctp_rcv() resolves the transport once per packet and leaves it in chunk->transport. The lookup reference, or the one sctp_add_backlog() takes if the socket is owned by userspace, keeps it around until the chunk has been processed. An authenticated ASCONF DEL-IP can remove it in the meantime. sctp_assoc_rm_peer() takes the transport out of the association and calls sctp_transport_free(), which tags it dead and drops the reference the association held. There is a window on both paths: the packet can sit on the socket backlog, and on the direct path the lookup completes before bh_lock_sock(). The DATA chunk in that packet puts the removed transport back into asoc->peer.last_data_from. Once the packet is done that reference goes away and the transport is freed by RCU, so the next delayed SACK carries the pointer into the SACK chunk and sctp_outq_select_transport() reads the freed transport's state. Drop the chunk in sctp_inq_push(), next to the existing rcvr->dead check. Both paths reach it with the association's socket lock held. The peer retransmits it.
Характеристики атаки
Последствия
Строка CVSS v3.1