CVE-2026-98996 in Linux
الملخص
بحسب VulDB • 23/10/2026
في نواة لينكس، تم حل الثغرة التالية:
fs: عدم إلغاء تحميل النقاط المشغولة بصمت (silently)
توجد الدالة المساعدة propagate_mount_busy() لتحديد ما إذا كان الإلغاء المتزامن يمكن أن ينجح. وتقوم بذلك من خلال النظر إلى نسخ الضحايا في نقاط التجميع التي ينشر إليها الوالد الخاص بها. واحدة من تلك الوظائف تنتمي إلى "جحيم النشر" (propagation hell).
تتخطى الدالة نسخةً تحتوي على نقاط تجميد تابعة لها، باستثناء حالة وجود نقطة تجميع فرعية واحدة فقط تغطي جذر النسخة. كان هذا الخوارزمي دقيقًا في السابق. لم يعد كذلك الآن.
في الأصل، كانت تُزال فقط النسخ التي لا تحتوي على فروع (childless) أثناء النشر. وأدى الإصدار 1064f874abc0 ("mnt: إخفاء نقاط التجميع تحت أخرى بدلاً من إنشاء ظلال/نقاط تجميع جانبية.") في النهاية إلى إضافة النقاط المشمولة بالتغطية لكلا الجانبين دفعة واحدة.
ثم ظهر الإصدار 99b19d16471e ("mnt: معالجة إلغاء التحميل أثناء النشر بزيارة نقاط التجميد بأي ترتيب") وبدأ بإزالة المزيد من النسخ مقارنة بالماضي:
[1]: تتم إزالة نسخة نقطة التجميع عندما يكون كل فرع لها إما نقطة تغطية (overmount) له أو نسخة من الضحية نفسها. في الحالة الأولى، يتم إعادة تعيين الوالد لنقطة التغطية. وفي الحالة الثانية، ستتم إزالة النسخة الخاصة بالضحية.
لذلك انتهى الأمر بإعادة كتابة propagate_umount() دون تعديل propagate_mount_busy(). والآن لا تنظر propagate_mount_busy() إلى نسخ الضحية التي تحتوي على طفلين أو أكثر، ولا الطفل الوحيد الذي ليس نقطة تغطية (overmount).
إذن، أي نسخة من هذه الأنواع في [1] لا يتم التحقق من المراجع الخاصة بها. النتيجة هي أن إلغاء التحميل المتزامن ينجح، مما يؤدي إلى سحب نقطة تجميع ما زالت قيد الاستخدام.
يمكن لحاوية (container) أن تواجه هذا الموقف مع نقاط التجميد الخاصة بها. حيث يشترك المضيف (host) في شجرة مع الحاوية، ويحتوي المضيف على نقطة تجميع داخل تلك الشجرة:
mount -t tmpfs none /mnt mount --make-shared /mnt mount -t tmpfs none /mnt/a
تكون /mnt الخاصة بالحاوية نسخة عابدة (slave copy) لنقطة التجميع في المضيف. تأخذ الحاوية الآن نسخة منفصلة من الشجرة وتقوم بتثبيت هذه النسخة تحت نسخها المنتشرة من /mnt/a، مع الاحتفاظ بمعرف الملف (file descriptor) للشجرة مفتوحًا:
unshare -m --propagation unchanged mount --make-rslave / fd = open_tree(AT_FDCWD, "/mnt", OPEN_TREE_CLONE | AT_RECURSIVE) move_mount(fd, "", AT_FDCWD, "/mnt/a", MOVE_MOUNT_BENEATH)
grep /mnt /proc/self/mountinfo 775 355 ... /mnt ... master:646 777 775 ... /mnt/a ... master:646 776 777 ... /mnt/a ... master:647 778 777 ... /mnt/a/a ... master:647
الشجرة المرفقة الآن (777) مثبتة تحت نسخة الحاوية من /mnt/a. وهذا هو المكان الذي توجد فيه أيضًا نقطة تجميع المضيف (كما يُرى من مساحة اسم التجميع في المضيف). لذا فإن النسخة المنتشرة (776) لنقطة تجميع المضيف تقع فوق جذرها، والنسخة منها (778) موجودة داخلها. الآن يشغل المضيف:
umount /mnt/a
وينجح الأمر. تختفي الشجرة المنقولة والشبكة الموجودة بداخلها من الحاوية. تتبقى فقط النسخة المنتشرة ويتم إعادة تعيين والدها إلى المكان الذي كانت عليه سابقًا:
grep /mnt /proc/self/mountinfo 775 355 ... /mnt ... master:646 776 775 ... /mnt/a ...
ولكن معرف الملف لا يزال يشير إلى الشجرة المنقولة. لذا فإن إلغاء التحميل المتزامن فصل نقطة تجميع ما زالت قيد الاستخدام.
علّم propagate_mount_busy() نفس الفحوصات التي تقوم بها propagate_umount(). تتحقق الآن من وجود نسخة ضحية واحدة بدون فروع، والتي يمكن الافتراض بأن MNT_LOCKED تم مسحها في كل نسخة كما تفعل propagate_umount(). تشكل النسخ سلاسل (chains). بعبارة أخرى، عندما تستقبل النسخة نفسها نشرًا من والد الضحية، فإن نقطة التجميع الموجودة عند نفس موقع التجميد داخل تلك النسخة هي أيضًا نسخة. يمكن التحقق مما إذا كانت نقطة تجميع تتلقى نشرًا من ضحية ما ببساطة عن طريق المشي عبر masters الخاصة بها. امشِ كل سلسلة مرة واحدة من أعلىها لضمان بقاء النسخ المتداخلة خطية (linear). تحقق من كل مرجع لمرة واحدة لكل نسخة يتم إلغاء تحميلها.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.