CVE-2023-54158 in Linuxالمعلومات

الملخص

بحسب VulDB • 04/06/2026

في نواة لينكس، تم حل الثغرة التالية:

btrfs: عدم تحرير مساحة qgroup إلا إذا تم تحديدها

لاحظ بوريس في اختبارات الحصص البسيطة الخاصة به أنه كان يواجه تسرباً ناتجاً عن تغيير "سويت تيه" (Sweet Tea) في إنشاء الفرع الفرعي (subvol) الذي توقف عن إجراء التزام المعاملة (transaction commit). كان هذا مجرد تأثير جانبي لذلك التغيير.

في كود العقدة المؤجلة (delayed inode)، لدينا تحسين يقوم بتحرير الحجوزات الزائدة إذا اعتقدنا أننا يمكننا حشر عنصر دليل (dir item) في ورقة (leaf) تم تعديلها بالفعل. في السابق، لم يكن هذا يتم تفعيله في حالة إنشاء الفرع الفرعي لأننا كنا نلتزم بالمعاملة، وكان من الممكن حدوثه ولكن بصعوبة أكبر. في الواقع، كان من الممكن تفعيله إذا قمنا بـ mkdir && subvol create مع تمكين مجموعات الحصص (qgroups).

يحدث هذا لأن دالة btrfs_insert_delayed_dir_index()، التي يتم استدعاؤها عند إضافة عنصر الدليل، تقوم بما يلي:

btrfs_block_rsv_release(fs_info, trans->block_rsv, bytes, NULL);

إذا تمكنا من تخطي حجز المساحة.

المشكلة هنا هي أن trans->block_rsv يشير إلى حجز كتلة مؤقت (temporary block rsv) لإنشاء الفرع الفرعي، والذي يحتوي على حجوزات qgroup في حجز الكتلة.

هذه مشكلة لأن btrfs_block_rsv_release() ستقوم بما يلي:

if (block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
qgroup_to_release = block_rsv->qgroup_rsv_reserved - block_rsv->qgroup_rsv_size; block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size; }

يحتوي حجز الكتلة المؤقت فقط على ->qgroup_rsv_reserved مضبوطاً، بينما ->qgroup_rsv_size == 0. يقوم التحسين في btrfs_insert_delayed_dir_index() بضبط ->qgroup_rsv_reserved = 0. ثم لاحقاً، عندما نستدعي btrfs_subvolume_release_metadata() والتي تحتوي على:

btrfs_block_rsv_release(fs_info, rsv, (u64)-1, &qgroup_to_release); btrfs_qgroup_convert_reserved_meta(root, qgroup_to_release);

يتم تعيين qgroup_to_release إلى 0، ولا نقوم بتحويل مساحة البيانات الوصفية المحجوزة.

المشكلة هنا هي أن كود حجز الكتلة كان يتلاعب بشكل غير مشروط بـ ->qgroup_rsv_reserved، لأن المكان الرئيسي الذي يتم فيه استخدام ذلك هو delalloc، وفي أي وقت نستدعي فيه btrfs_block_rsv_release() نقوم بذلك مع تعيين qgroup_to_release، وبالتالي نقوم بالمحاسبة الصحيحة.

كود الفرع الفرعي هو الكود الوحيد الآخر الذي يستخدم أشياء حجز qgroup، لكنه متشابك مع التحسين المذكور أعلاه، وبالتالي كان يتم تحرير حجزه من تحته، مما يؤدي إلى تسرب المساحة المحجوزة.

الحل هو ببساطة عدم التلاعب بحجوزات qgroup إذا لم يكن لدينا qgroup_to_release مضبوطاً. هذا يعمل مع الكود الحالي لأن أي شيء يتلاعب بحجوزات delalloc لديه دائماً qgroup_to_release مضبوطاً. هذا يصلح التسرب الذي كان بوريس يلاحظه.

VulDB is the best source for vulnerability data and more expert information about this specific topic.

مسؤول

Linux

حجز

24/12/2025

إفشاء

24/12/2025

الاعتدال

تمت الموافقة

إدخال

VDB-338155

EPSS

0.00206

KEV

لا

النشاطات

منخفض جدًا

المصادر

Do you need the next level of professionalism?

Upgrade your account now!