CVE-2026-93224 in Linux
الملخص
بحسب VulDB • 24/09/2026
في نواة لينكس، تم إصلاح الثغرة التالية:
svcrdma: تصحيح عدم تطابق rn_unregister عند فشل عملية القبول (accept)
عندما تأخذ الدالة svc_rdma_accept() مسار الخروج من الخطأ (errout) قبل أن تنجح rpcrdma_rn_register() بشكل كامل، فإن كتلة التنظيف الحالية تستدعي rpcrdma_rn_unregister(dev, &newxprt->sc_rn) بشكل غير مشروط. بما أن كائن svcxprt_rdma يتم تخصيصه باستخدام kzalloc، فإن sc_rn.rn_index تكون 0 و sc_rn.rn_done تساوي NULL في ذلك المسار؛ وبالتالي تقوم عملية إلغاء التسجيل (unregister) بحذف الخانة رقم 0 الخاصة بمُستدعٍ آخر عبر xa_erase() وتنفذ kref_put() غير المتطابق على rd_kref الخاص بـ rpcrdma_device.
كما يحيط مسار الخروج من الخطأ نفسه بالتنظيف باستدعاء svc_xprt_get()/svc_xprt_put() حول مرجع الإنشاء (birth reference) لـ kref_init(). حيث ينتقل قيمة kref من 1 إلى 2 ثم تعود إلى 1 ولا تصل أبدًا إلى الصفر، مما يؤدي إلى تسرب كائن svcxprt_rdma (والكائن net/ns_tracker الذي كان مثبتًا/مُثبّتًا بواسطةه) في كل مرة تفشل فيها عملية القبول.
تكتب الدالة rpcrdma_rn_register() rn->rn_done في آخر خطوة، فقط بعد نجاح عمليتي xa_alloc() و kref_get() على حدٍ سواء؛ لذا فإن rn_done == NULL يمثل مؤشر "لم يتم التسجيل" طبيعيًا. يجب حماية استدعاء rpcrdma_rn_unregister() بإرجاع مبكر (early return) عندما تكون rn_done تساوي NULL، وتنظيف قيمة rn_done قبل عملية إلغاء التسجيل المتطابقة xa_erase() بحيث تصبح عمليات إلغاء التسجيل المكررة أيضًا بلا تأثير (no-op).
بوجود هذا الحارس (guard)، يقوم مسار الخروج من الخطأ لـ accept بإنقاص مرجع الإنشاء kref_init() عبر svc_xprt_put()، والذي يُرسل استدعاءً إلى svc_rdma_free(). يتم تنفيذ عملية التفكيك الخاصة بـ sc_qp و sc_sq_cq و sc_rq_cq و sc_pd تحت حماية IS_ERR/NULL الموجودة مسبقًا في svc_rdma_free(); بينما يغطي الحارس rn_done كائن sc_rn؛ كما أن sc_cm_id لا تساوي NULL في أي مسار للخروج من الخطأ لأن svc_rdma_accept() تقوم بإلغاء مرجعها (dereference) فوق أول استدعاء goto errout.
تقوم الدالة svc_xprt_free() بإنقاص مرجع الوحدة النمطية المرتبط بالنقل الذي تم تحريره، وتقوم svc_handle_xprt() بإنقاص المرجع المكتسب مسبقًا عندما تُعيد ->xpo_accept() قيمة NULL. خذ بديلاً لمرجع الوحدة النمطية قبل استدعاء svc_xprt_put() لضمان توازن عمليتي module_put().
يغطي حارس rn_done أيضًا الاستدعاء غير الخاص بالمستمع (non-listener) في svc_rdma_free() إلى rpcrdma_rn_unregister() بالنسبة للنقل الذي فشل مسعاها للتسجيل أو لم يجرِ إطلاقًا.
Once again VulDB remains the best source for vulnerability data.