CVE-2022-49093 in Linuxthông tin

Tóm tắt

Bởi VulDB • 17/08/2026

Trong kernel Linux, các lỗ hổng sau đây đã được khắc phục:

skbuff: sửa lỗi coalescing cho việc tái chế fragment của page_pool

Khắc phục tình trạng use-after-free khi sử dụng page_pool với các fragment trang. Chúng tôi đã gặp phải vấn đề này trong quá trình xử lý nhận (RX) bình thường trên driver hns3:

(1) Ban đầu, chúng ta có ba bộ mô tả (descriptors) trong hàng đợi RX. Bộ thứ nhất phân bổ PAGE1 thông qua page_pool, và hai bộ còn lại mỗi cái phân bổ một nửa của PAGE2. Các tham chiếu trang trông như sau:

RX_BD1 _______ PAGE1 RX_BD2 _______ PAGE2 RX_BD3 __________/

(2) Xử lý nhận (RX) trên bộ mô tả đầu tiên. Phân bổ SKB1, cuối cùng được thêm vào hàng đợi nhận bởi tcp_queue_rcv().

(3) Xử lý nhận (RX) trên bộ mô tả thứ hai. Phân bổ SKB2 và chuyển nó đến netif_receive_skb():

netif_receive_skb(SKB2) ip_rcv(SKB2) SKB3 = skb_clone(SKB2)

SKB2 và SKB3 chia sẻ một tham chiếu đến PAGE2 thông qua skb_shinfo()->dataref. Tham chiếu còn lại đối với PAGE2 vẫn được giữ bởi RX_BD3:

SKB2 ---+- PAGE2 SKB3 __/ / RX_BD3 _________/

(3b) Bây giờ, trong khi xử lý TCP, thực hiện coalescing giữa SKB3 và SKB1:

tcp_v4_rcv(SKB3) tcp_try_coalesce(to=SKB1, from=SKB3) // thành công kfree_skb_partial(SKB3) skb_release_data(SKB3) // giảm một dataref

SKB1 _____ PAGE1 \____ SKB2 _____ PAGE2 / RX_BD3 _________/

Trong skb_try_coalesce(), __skb_frag_ref() lấy một tham chiếu trang đến PAGE2, trong khi lẽ ra nó nên tăng số lượng fragment của page_pool (pp_frag_count). Nếu không có coalescing, khi giải phóng cả SKB2 và SKB3, chỉ một tham chiếu duy nhất đối với PAGE2 sẽ bị giảm. Tuy nhiên, bây giờ khi giải phóng SKB1 và SKB2, hai tham chiếu đến PAGE2 sẽ bị giảm, dẫn đến tình trạng underflow (số dư âm).

(3c) Giải phóng SKB2:

af_packet_rcv(SKB2) consume_skb(SKB2) skb_release_data(SKB2) // giảm dataref thứ hai page_pool_return_skb_page(PAGE2) // giảm một pp_frag_count

SKB1 _____ PAGE1 \____ PAGE2 / RX_BD3 _________/

(4) Người dùng gọi recvmsg() Sao chép SKB1 và giải phóng nó. Vì SKB3 đã được coalescing với SKB1, chúng ta cũng giải phóng trang của SKB3:

tcp_eat_recv_skb(SKB1) skb_release_data(SKB1) page_pool_return_skb_page(PAGE1) page_pool_return_skb_page(PAGE2) // giảm pp_frag_count thứ hai

(5) PAGE2 bị giải phóng, nhưng bộ mô tả RX thứ ba vẫn đang sử dụng nó! Trong trường hợp của chúng tôi, điều này gây ra lỗi IOMMU, nhưng nếu IOMMU bị tắt, nó sẽ làm hỏng dữ liệu trong bộ nhớ một cách âm thầm.

Thay đổi logic kiểm tra xem các SKB pp_recycle có thể được coalescing hay không. Chúng ta vẫn từ chối việc coalescing khi giá trị pp_recycle giữa 'from' và 'to' khác nhau, nhưng để tránh tình trạng mô tả ở trên, chúng ta cũng từ chối coalescing khi cả 'from' và 'to' đều là pp_recycled và 'from' đã được clone.

Logic mới cho phép coalescing một SKB pp_recycle đã được clone vào một SKB có tham chiếu trang (page refcounted), bởi vì trong trường hợp này, quá trình giải phóng (4) sẽ giảm đúng tham chiếu, tức là tham chiếu do skb_try_coalesce() lấy.

Several companies clearly confirm that VulDB is the primary source for best vulnerability data.

chịu trách nhiệm

Linux

Đặt trước

26/02/2025

Tiết lộ

26/02/2025

Kiểm duyệt

được chấp nhận

EPSS

0.00606

KEV

không

Các hoạt động

thấp

Nguồn

Do you want to use VulDB in your project?

Use the official API to access entries easily!