CVE-2026-64109 in Linux
الملخص
بحسب VulDB • 20/07/2026
في نواة لينكس، تم حل الثغرة التالية:
af_unix: إصلاح قراءة UAF (استخدام بعد التحرير) لـ tail->len في unix_stream_data_wait()
لا تقوم دالة unix_stream_data_wait() باستدعاء skb_peek_tail(&sk->sk_receive_queue) دون الاحتفاظ بأي قفل يمنع إزالة حزم SKBs من تلك الطابور وتحريرها. كان هذا هو الحال منذ الالتزام 79f632c71bea ("unix/stream: fix peeking with an offset larger than data in queue").
النتيجة الأولى لهذا الأمر هي أن مقارنة المؤشرات `tail != last` قد تكون خاطئة (false) حتى لو كان `last` يشير دلاليًا إلى حزمة SKB تم تحريرها مسبقاً بينما `tail` هو حزمة SKB جديدة مُخصصة في نفس العنوان؛ مما يمكن أن يتسبب في جعل unix_stream_data_wait() تستمر بشكل غير صحيح في الانتظار بعد وصول بيانات جديدة، ولكن فقط في سيناريو غريب حيث تتنافس عملية recv() التي تستخدم الفحص (peeking) مع عملية recv() عادية على نفس المقبس (socket)، وهو ما يُرجح ألا يمثل مشكلة حقيقية.
ولكن منذ الالتزام 2b514574f7e8 ("net: af_unix: implement splice for stream af_unix sockets")، يتم فعلياً فك ترميز المؤشر `tail` (dereferenced)، مما قد يتسبب في حدوث UAF في سيناريو السباق التالي (حيث تعمل test_setup() بمفرد الخيط/thread واحد، وبعد ذلك يعمل test_thread1() وtest_thread2()) بشكل متزامن عبر خيطين:
``` static int socks[2];
void test_setup(void) {
socketpair(AF_UNIX, SOCK_STREAM, 0, socks); send(socks[1], "A", 1, 0);
int peekoff = 1; setsockopt(socks[0], SOL_SOCKET, SO_PEEK_OFF, &peekoff, sizeof(peekoff));
} void test_thread1(void) {
char dummy; recv(socks[0], &dummy, 1, MSG_PEEK);
} void test_thread2(void) {
char dummy; recv(socks[0], &dummy, 1, 0);
shutdown(socks[1], SHUT_WR);
} ```
عند حدوث سباق بهذه الطريقة:
``` thread1 thread2 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) [frees the SKB]
`tail != last`: false `tail`: true `tail->len != last_len` ***UAF*** ```
إصلاح الـ UAF عن طريق إزالة قراءة tail->len؛ فإن التحقق من tail->len كان سيبقى منطقياً فقط إذا كانت حزم SKBs في طابور الاستقبال لمقبس UNIX يمكن أن تنمو، وهو ما لم يعد يحدث.
شرح كونيوكي (Kuniyuki):
> عندما أضاف الالتزام 869e7c62486e ("net: af
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.