memfd_secret(2)

الاسم
memfd_secret - إنشاء ملف مجهول قائم على RAM للوصول إلى مناطق الذاكرة السرية

المكتبة
مكتبة سي المعيارية (libc، -lc)

موجز

#include <sys/syscall.h>      /* تعريف ثوابت SYS_* */
#include <unistd.h>

int syscall(SYS_memfd_secret, unsigned int flags);

ملاحظة: لا توفر glibc غلافًا لـ memfd_secret()، مما يستلزم استخدام syscall(2).

الوصف
ينشئ memfd_secret() ملفًا مجهولًا قائمًا على RAM ويعيد واصف ملف يشير إليه. يوفر الملف طريقة لإنشاء والوصول إلى مناطق الذاكرة بحماية أقوى من الملفات العادية القائمة على RAM وتعيينات الذاكرة المجهولة. بمجرد إغلاق جميع المراجع المفتوحة للملف، يُحرر آليًا. يُضبط الحجم المبدئي للملف على 0. بعد الاستدعاء، يجب ضبط حجم الملف باستخدام ftruncate(2).

مناطق الذاكرة الداعمة للملف المنشأ بـ memfd_secret(2) مرئية فقط للعمليات التي لديها وصول إلى واصف الملف. تُزال منطقة الذاكرة من جداول صفحات النواة، وتقوم جداول صفحات العمليات التي تحمل واصف الملف فقط بتعيين الذاكرة الفعلية المقابلة. (وبالتالي، لا يمكن للنواة نفسها الوصول إلى الصفحات في المنطقة، بحيث لا يمكن، على سبيل المثال، تمرير المؤشرات إلى المنطقة إلى استدعاءات النظام.)

قد تُجمع القيم التالية بعملية OR بتية في flags للتحكم في سلوك memfd_secret():

FD_CLOEXEC
    يضبط علم الإغلاق عند التنفيذ على واصف الملف الجديد، مما يتسبب في إزالة المنطقة من العملية عند execve(2). انظر وصف علم O_CLOEXEC في open(2)

كقيمة إرجاع، يُعيد memfd_secret() واصف ملف جديد يشير إلى ملف مجهول. يُفتح واصف الملف هذا للقراءة والكتابة معًا (O_RDWR) ويُضبط O_LARGEFILE لواصف الملف.

فيما يتعلق بـ fork(2) و execve(2)، تنطبق الدلالات المعتادة على واصف الملف المنشأ بواسطة memfd_secret(). ترث العملية الابنة الناتجة عن fork(2) نسخة من واصف الملف وتشير إلى نفس الملف. يُحتفظ بواصف الملف عبر execve(2)، ما لم يُضبط علم الإغلاق عند التنفيذ.

تُقفل منطقة الذاكرة في الذاكرة بنفس الطريقة كما في mlock(2)، بحيث لا تُكتب أبدًا في المبادلة، ويُثبط السبات طالما توجد أي أوصاف لـ memfd_secret(). ومع ذلك، لن يحاول تنفيذ memfd_secret() ملء النطاق بأكمله أثناء استدعاء mmap(2) الذي يرفق المنطقة بمساحة عنوان العملية؛ بدلاً من ذلك، تُخصص الصفحات فقط عند حدوث خطأ فيها. تخضع كمية الذاكرة المسموح بها لتعيينات الذاكرة لواصف الملف لنفس قواعد mlock(2) ولا يمكن أن تتجاوز RLIMIT_MEMLOCK.

قيمة الإرجاع
عند النجاح، يُعيد memfd_secret() واصف ملف جديد. عند الخطأ، يُعاد -1 ويُضبط errno للإشارة إلى الخطأ.

الأخطاء

EINVAL
    تضمن flags بتات غير معروفة.

EMFILE
    وُصل إلى الحد الأقصى لواصفات الملفات المفتوحة لكل عملية.

EMFILE
    وُصل إلى الحد الأقصى لإجمالي عدد الملفات المفتوحة على مستوى النظام.

ENOMEM
    لم تكن الذاكرة كافية لإنشاء ملف مجهول جديد.

ENOSYS
    memfd_secret() غير مطبق على هذه البنية، أو لم يُفعّل في سطر أوامر النواة باستخدام secretmem_enable=1.

المعايير
لينكس.

التاريخ
لينكس 5.14.

قبل لينكس 6.5، كان memfd_secret() معطلًا مبدئيًا ومتاحًا فقط إذا فعّله مسؤول النظام باستخدام معامل النواة "secretmem.enable=y".

ملاحظات
صُمم استدعاء النظام memfd_secret() للسماح لعملية في مساحة المستخدم بإنشاء نطاق من الذاكرة لا يمكن لأي شخص آخر الوصول إليه - بما في ذلك النواة. لا يوجد ضمان بنسبة 100% بأن النواة لن تتمكن من الوصول إلى نطاقات الذاكرة المدعومة بـ memfd_secret() في أي ظرف، ولكن مع ذلك، من الأصعب بكثير تسريب البيانات من هذه المناطق.

يوفر memfd_secret() الحمايات التالية:

•   حماية معززة (بالاشتراك مع جميع أنظمة منع الهجمات الأخرى داخل النواة) ضد هجمات ROP. يعني غياب أي بدائية داخل النواة للوصول إلى الذاكرة المدعومة بـ memfd_secret() أن هجوم ROP ذا الأداة الواحدة لا يمكنه العمل لتسريب البيانات. سيحتاج المهاجم إلى إيجاد عدد كافٍ من أدوات ROP لإعادة بناء إدخالات جدول الصفحات المفقودة، مما يزيد بشكل كبير من صعوبة الهجوم، خاصةً عند وجود حمايات أخرى مثل حد حجم مكدس النواة وعشوائية تخطيط مساحة العنوان.

•   يمنع تعريضات الذاكرة عبر العمليات في مساحة المستخدم. بمجرد تخصيص منطقة لتعيين ذاكرة memfd_secret()، لا يمكن للمستخدم تمريرها عن طريق الخطأ إلى النواة لنقلها إلى مكان ما. لا يمكن الوصول إلى صفحات الذاكرة في هذه المنطقة عبر الخريطة المباشرة، وهي ممنوعة في get_user_pages.

•   يقوي ضد عيوب النواة المستغلة. للوصول إلى مناطق الذاكرة المدعومة بـ memfd_secret()، سيحتاج هجوم من جانب النواة إما إلى التجول في جداول الصفحات وإنشاء جداول جديدة، أو إنشاء عملية جديدة ذات امتياز في مساحة المستخدم لتسريب الأسرار باستخدام ptrace(2).

لمنع تسريبات البيانات المحتملة لمناطق الذاكرة المدعومة بـ memfd_secret() من صورة السبات، يُمنع السبات عند وجود مستخدمين نشطين لـ memfd_secret().

انظر أيضًا
fcntl(2), ftruncate(2), mlock(2), memfd_create(2), mmap(2), setrlimit(2)

ترجمة
تُرجمت هذه الصفحة من الدليل بواسطة زايد السعيدي <zayed.alsaidi@gmail.com>

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 (https://www.gnu.org/licenses/gpl-3.0.html) أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

إذا وجدت أي أخطاء في ترجمة صفحة الدليل هذه، يرجى إرسال بريد إلكتروني إلى قائمة بريد المترجمين: kde-l10n-ar@kde.org.