В ядре Linux устранена следующая уязвимость:
rxrpc: не перемещать просматриваемое OOB-сообщение в ожидающую очередь.
rxrpc_recvmsg_oob() извлекает полученное сообщение oob из Recvmsg_oobq и
если необходим ответ, перемещает его в дерево pending_oobq. Однако,
только отсоединение от Recvmsg_oobq защищено MSG_PEEK; переход на
pending_oobq всегда запускается. В результате чтение запроса с помощью MSG_PEEK оставляет skb включенным.
Recvmsg_oobq, а также добавив его в pending_oobq. Поскольку структура
rbnode sk_buff делит хранилище со своими указателями next и prev,
rb_insert_color() перезаписывает связь списка и skb, который содержит
единственная ссылка становится доступной из обеих очередей одновременно. Когда сокет закрывается, обе очереди очищаются по очереди.
Пока
слив Recvmsg_oobq, __skb_unlink() следует за следующим и предыдущим
указатели на то, что rbnode перезаписал и пишет на неправильный адрес. Кроме того,
поскольку skb содержит одну ссылку, но освобождается от каждой очереди, обе
skb и ссылка на соединение, которую он содержит, освобождаются дважды. Это
приводит к повреждению памяти и использованию после освобождения, вызванному
Недостаток счетчика ссылок на соединение.
MSG_PEEK не потребляет сообщение из очереди, поэтому просто отсоедините его.
из Recvmsg_oobq, а затем переместите его в pending_oobq или освободите его, когда
сообщение фактически потребляется.
Показать оригинальное описание (EN)
In the Linux kernel, the following vulnerability has been resolved: rxrpc: Don't move a peeked OOB message onto the pending queue rxrpc_recvmsg_oob() takes a received oob message off recvmsg_oobq and, if a response is needed, moves it onto the pending_oobq tree. However, only the unlink from recvmsg_oobq is guarded by MSG_PEEK; the move onto pending_oobq always runs. As a result, reading a challenge with MSG_PEEK leaves the skb on recvmsg_oobq while also adding it to pending_oobq. Since struct sk_buff's rbnode shares storage with its next and prev pointers, rb_insert_color() overwrites the list linkage, and the skb, which holds a single reference, becomes reachable from both queues at once. When the socket is closed both queues are drained in turn. While draining recvmsg_oobq, __skb_unlink() follows the next and prev pointers that rbnode has overwritten and writes to a bad address. Also, as the skb holds a single reference but is freed from each queue, both the skb and the connection reference it holds are released twice. This leads to memory corruption and to a use-after-free caused by the connection refcount underflow. MSG_PEEK does not consume the message from the queue, so only unlink it from recvmsg_oobq and then move it onto pending_oobq or free it when the message is actually consumed.
Характеристики атаки
Последствия
Строка CVSS v3.1