Scroll to navigation

القدرات(7) Miscellaneous Information Manual القدرات(7)

الاسم

القدرات - نظرة عامة على قدرات لينكس

الوصف

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

بدءًا من لينكس 2.2، يقسم لينكس الامتيازات المرتبطة تقليديًا بالمستخدم الخارق إلى وحدات متميزة تُعرف باسم القدرات، والتي يمكن تفعيلها وتعطيلها بشكل مستقل. القدرات هي سمة لكل خيط (thread).

قائمة القدرات

توضح القائمة التالية القدرات المطبقة في لينكس، والعمليات أو السلوكيات التي تسمح بها كل قدرة:

تفعيل وتعطيل تدقيق النواة؛ وتغيير قواعد مرشح التدقيق؛ واسترداد حالة التدقيق وقواعد الترشيح.
السماح بقراءة سجل التدقيق عبر مقبس netlink متعدد البث.
كتابة السجلات في سجل تدقيق النواة.
استخدام الميزات التي يمكنها منع تعليق النظام (epoll(7) EPOLLWAKEUP، و /proc/sys/wake_lock).
استخدام عمليات BPF المتميزة؛ انظر bpf(2) و bpf-helpers(7).
أُضيفت هذه القدرة في لينكس 5.8 لفصل وظائف BPF عن قدرة CAP_SYS_ADMIN المحملة بأكثر من طاقتها.
تحديث /proc/sys/kernel/ns_last_pid (انظر pid_namespaces(7)
استخدام ميزة set_tid في clone3(2)؛
قراءة محتويات الروابط الرمزية في /proc/pid/map_files للعمليات الأخرى.
أُضيفت هذه القدرة في لينكس 5.9 لفصل وظائف الفحص/الاستعادة عن قدرة CAP_SYS_ADMIN المحملة بأكثر من طاقتها.
إجراء تغييرات عشوائية على معرفات المستخدمين والمجموعات للملفات (انظر chown(2)).
تخطي فحوصات أذونات القراءة والكتابة والتنفيذ للملفات. (DAC هو اختصار لـ "discretionary access control" أو التحكم في الوصول الاختياري.)
تخطي فحوصات أذونات قراءة الملفات وفحوصات أذونات قراءة وتنفيذ الدلائل؛
استدعاء open_by_handle_at(2)؛
استخدام علامة AT_EMPTY_PATH في linkat(2) لإنشاء رابط لملف يشار إليه بواصف ملف (file descriptor).
تخطي فحوصات الأذونات في العمليات التي تتطلب عادةً مطابقة معرف مستخدم نظام الملفات للعملية مع معرف مستخدم الملف (مثل chmod(2) و utime(2))، باستثناء العمليات التي تغطيها CAP_DAC_OVERRIDE و CAP_DAC_READ_SEARCH؛
ضبط علامات العقدة (inode) (انظر FS_IOC_SETFLAGS(2const)) على ملفات عشوائية؛
ضبط قوائم التحكم في الوصول (ACLs) على ملفات عشوائية؛
تجاهل البتة اللزجة (sticky bit) للدليل عند حذف ملف؛
تعديل السمات الممتدة لـ المستخدم في دليل لزج مملوك لأي مستخدم؛
تحديد O_NOATIME لملفات عشوائية في open(2) و fcntl(2).
عدم مسح بتات وضع معرف المستخدم المعين (set-user-ID) ومعرف المجموعة المعين (set-group-ID) عند تعديل ملف؛
ضبط بتة معرف المجموعة المعين (set-group-ID) لملف لا يتطابق معرف مجموعته (GID) مع نظام الملفات أو أي من معرفات المجموعات الإضافية للمستدعِي.
قفل الذاكرة (mlock(2)، و mlockall(2)، و mmap(2)، و shmctl(2)
تخصيص ذاكرة باستخدام الصفحات الضخمة (memfd_create(2)، و mmap(2)، و shmctl(2)).
تخطي فحوصات الأذونات للعمليات على كائنات System V IPC.
تخطي فحوصات الأذونات لإرسال الإشارات (انظر kill(2)). وهذا يتضمن استخدام عملية KDSIGACCEPT في ioctl(2).
إنشاء عقود إيجار (leases) على ملفات عشوائية (انظر fcntl(2)).
تعيين علامتي العنصر FS_APPEND_FL و FS_IMMUTABLE_FL (انظر FS_IOC_SETFLAGS(2const)).
السماح بضبط MAC أو تغيير حالته. مطبق لوحدة أمن لينكس Smack (LSM).
تخطي التحكم الإلزامي في الوصول (MAC). مطبق لوحدة Smack LSM.
إنشاء ملفات خاصة باستخدام mknod(2).
إجراء عمليات متنوعة متعلقة بالشبكة:
ضبط الواجهة؛
إدارة جدار حماية IP والتنكر (masquerading) والمحاسبة؛
تعديل جداول التوجيه؛
الارتباط بأي عنوان للوكيل الشفاف؛
ضبط نوع الخدمة (TOS)؛
مسح إحصائيات التعريف؛
ضبط الوضع المختلط (promiscuous mode)؛
تفعيل البث المتعدد؛
استخدام setsockopt(2) لضبط خيارات المقبس التالية: SO_DEBUG، و SO_MARK، و SO_PRIORITY (لأولوية خارج النطاق من 0 إلى 6)، و SO_RCVBUFFORCE، و SO_SNDBUFFORCE.
ربط مقبس بمنافذ متميزة في نطاق الإنترنت (أرقام منافذ أقل من 1024).
(غير مستخدمة) إجراء بث للمقابس، والاستماع للبث المتعدد.
استخدام مقابس RAW و PACKET؛
الارتباط بأي عنوان للوكيل الشفاف.
استخدام آليات مراقبة الأداء المتنوعة، بما في ذلك:
استدعاء perf_event_open(2)؛
استخدام عمليات BPF المتنوعة التي لها آثار على الأداء.
أُضيفت هذه القدرة في لينكس 5.8 لفصل وظائف مراقبة الأداء عن قدرة CAP_SYS_ADMIN المحملة بأكثر من طاقتها. انظر أيضًا ملف مصدر النواة Documentation/admin-guide/perf-security.rst.
إجراء تلاعبات عشوائية بمعرفات مجموعات العملية وقائمة معرفات المجموعات الإضافية؛
تزييف معرف المجموعة عند تمرير بيانات اعتماد المقبس عبر مقابس نطاق يونكس؛
كتابة تخطيط لمعرف المجموعة في مساحة اسم مستخدم (انظر user_namespaces(7)).
ضبط قدرات عشوائية على ملف.
منذ لينكس 5.12، أصبحت هذه القدرة مطلوبة أيضًا لتخطيط معرف المستخدم 0 في مساحة اسم مستخدم جديدة؛ انظر user_namespaces(7) للتفاصيل.
إذا كانت قدرات الملفات مدعومة (أي منذ لينكس 2.6.24): إضافة أي قدرة من مجموعة حدود الخيط المستدعي إلى مجموعته القابلة للتوريث؛ وإسقاط القدرات من مجموعة الحدود (عبر prctl(2) PR_CAPBSET_DROP)؛ وإجراء تغييرات على علامات securebits.
إذا كانت قدرات الملفات غير مدعومة (أي قبل لينكس 2.6.24): منح أو إزالة أي قدرة في مجموعة القدرات المسموح بها للمستدعي إلى أو من أي عملية أخرى. (هذه الخاصية لـ CAP_SETPCAP غير متاحة عندما تُضبط النواة لدعم قدرات الملفات، حيث أن لـ CAP_SETPCAP دلالات مختلفة تمامًا في هذه النوى.)
إجراء تلاعبات عشوائية بمعرفات مستخدمي العملية (setuid(2)، و setreuid(2)، و setresuid(2)، و setfsuid(2)
تزييف معرف المستخدم عند تمرير بيانات اعتماد المقبس عبر مقابس نطاق يونكس؛
كتابة تخطيط لمعرف المستخدم في مساحة اسم مستخدم (انظر user_namespaces(7)).
ملاحظة: هذه القدرة مُحمّلة بأكثر مما ينبغي؛ انظر ملاحظات لمطوري النواة أدناه.
إجراء مجموعة من عمليات إدارة النظام بما في ذلك: quotactl(2)، وmount(2)، وumount(2)، وpivot_root(2)، وswapon(2)، وswapoff(2)، وsethostname(2)، وsetdomainname(2)؛
إجراء عمليات syslog(2) ذات الامتيازات (منذ لينكس 2.6.37، يُفضل استخدام CAP_SYSLOG للسماح بمثل هذه العمليات)؛
إجراء أمر VM86_REQUEST_IRQ الخاص بـ vm86(2)؛
الوصول إلى نفس وظائف نقطة التحقق/الاستعادة التي تحكمها CAP_CHECKPOINT_RESTORE (لكن القدرة الأخيرة، الأضعف، هي المفضلة للوصول إلى تلك الوظائف).
إجراء نفس عمليات BPF التي تحكمها CAP_BPF (لكن القدرة الأخيرة، الأضعف، هي المفضلة للوصول إلى تلك الوظائف).
توظيف نفس آليات مراقبة الأداء التي تحكمها CAP_PERFMON (لكن القدرة الأخيرة، الأضعف، هي المفضلة للوصول إلى تلك الوظائف).
إجراء عمليتي IPC_SET وIPC_RMID على كائنات System V IPC العشوائية؛
تجاوز حد الموارد RLIMIT_NPROC؛
إجراء عمليات على السمات الموسعة trusted وsecurity (انظر xattr(7)
استخدام lookup_dcookie(2)؛
استخدام ioprio_set(2) لتعيين فئات جدولة المدخلات/المخرجات IOPRIO_CLASS_RT و(قبل لينكس 2.6.25) IOPRIO_CLASS_IDLE؛
تزوير معرف العملية (PID) عند تمرير بيانات الاستيثاق الخاصة بالمقبس عبر مقابس نطاق يونكس؛
تجاوز /proc/sys/fs/file-max، وهو الحد الشامل للنظام لعدد الملفات المفتوحة، في استدعاءات النظام التي تفتح ملفات (مثل: accept(2)، وexecve(2)، وopen(2)، وpipe(2)
توظيف أعلام CLONE_* التي تُنشئ مساحات أسماء جديدة باستخدام clone(2) وunshare(2) (لكن، منذ لينكس 3.8، إنشاء مساحات أسماء المستخدمين لا يتطلب أي قدرة)؛
الوصول إلى معلومات أحداث perf ذات الامتيازات؛
استدعاء setns(2) (يتطلب CAP_SYS_ADMIN في مساحة أسماء المستهدف
استدعاء fanotify_init(2)؛
إجراء عمليات KEYCTL_CHOWN وKEYCTL_SETPERM الخاصة بـ keyctl(2) ذات الامتيازات؛
إجراء عملية MADV_HWPOISON الخاصة بـ madvise(2)؛
توظيف TIOCSTI ioctl(2) لإدراج محارف في طابور مدخلات طرفية غير الطرفية التي يتحكم بها المستدعِي؛
توظيف استدعاء النظام المهجور nfsservctl(2)؛
توظيف استدعاء النظام المهجور bdflush(2)؛
إجراء عمليات ioctl(2) مختلفة ذات امتيازات على أجهزة كتلية؛
إجراء عمليات ioctl(2) مختلفة ذات امتيازات على نظام الملفات؛
إجراء عمليات ioctl(2) ذات امتيازات على جهاز /dev/random (انظر random(4)
تثبيت مرشح seccomp(2) دون الحاجة أولًا لضبط سمة الخيط no_new_privs؛
تعديل قواعد السماح/المنع لمجموعات التحكم في الأجهزة؛
توظيف عملية PTRACE_SECCOMP_GET_FILTER الخاصة بـ ptrace(2) لتفريغ مرشحات seccomp الخاصة بالمُتتبَّع؛
توظيف عملية PTRACE_SETOPTIONS الخاصة بـ ptrace(2) لتعليق حمائيات seccomp الخاصة بالمُتتبَّع (أي علم PTRACE_O_SUSPEND_SECCOMP
إجراء عمليات إدارية على العديد من مشغلات الأجهزة؛
تعديل قيم اللطافة (nice) للمجموعات الآلية عبر الكتابة في /proc/pid/autogroup (انظر sched(7)).
استخدام reboot(2) وkexec_load(2).
استخدام chroot(2)؛
تغيير مساحات أسماء الوصل باستخدام setns(2).
تحميل وتفريغ وحدات النواة (انظر init_module(2) وdelete_module(2)
قبل لينكس 2.6.25: إسقاط القدرات من مجموعة حدود القدرات الشاملة للنظام.
خفض قيمة لطافة (nice) العملية (nice(2)، وsetpriority(2)) وتغيير قيمة اللطافة للعمليات العشوائية؛
ضبط سياسات جدولة الوقت الحقيقي للعملية المستدعِية، وضبط سياسات الجدولة والأولويات للعمليات العشوائية (sched_setscheduler(2)، وsched_setparam(2)، وsched_setattr(2)
ضبط انجذاب وحدة المعالجة المركزية (CPU affinity) للعمليات العشوائية (sched_setaffinity(2)
ضبط فئة وأولوية جدولة المدخلات/المخرجات للعمليات العشوائية (ioprio_set(2)
تطبيق migrate_pages(2) على عمليات عشوائية والسماح بتهجير العمليات إلى عُقد عشوائية؛
تطبيق move_pages(2) على عمليات عشوائية؛
استخدام علم MPOL_MF_MOVE_ALL مع mbind(2) وmove_pages(2).
استخدام acct(2).
تتبع عمليات عشوائية باستخدام ptrace(2)؛
فحص المعلومات الحساسة للعمليات الأخرى عبر /proc (مثلاً، قراءة /proc/pid/maps، أو /proc/pid/mem، أو قراءة الروابط الرمزية /proc/pid/exe، أو /proc/pid/fd/*
تطبيق get_robust_list(2) على عمليات عشوائية؛
نقل البيانات من أو إلى ذاكرة عمليات عشوائية باستخدام process_vm_readv(2) وprocess_vm_writev(2)؛
فحص العمليات باستخدام kcmp(2)؛
إجراء عمليات فحص وتنقح عمليات أخرى ذات امتيازات. (انظر استخدامات دالة النواة ptrace_may_access().)
إجراء عمليات منافذ المدخلات/المخرجات (iopl(2) وioperm(2)
الوصول إلى /proc/kcore؛
توظيف عملية FIBMAP ioctl(2)؛
فتح الأجهزة للوصول إلى مسجلات x86 المحددة للطراز (MSRs، انظر msr(4)
تحديث /proc/sys/vm/mmap_min_addr؛
إنشاء تخطيطات ذاكرة عند عناوين أقل من القيمة المحددة بواسطة /proc/sys/vm/mmap_min_addr؛
تخطيط الملفات في /proc/bus/pci؛
فتح /dev/mem و/dev/kmem؛
إجراء أوامر أجهزة SCSI مختلفة؛
إجراء عمليات معينة على أجهزة hpsa(4) وcciss(4)؛
إجراء مجموعة من العمليات الخاصة بالأجهزة على أجهزة أخرى.
استخدام المساحة المحجوزة على أنظمة ملفات ext2؛
إجراء استدعاءات ioctl(2) للتحكم في تدوين ext3؛
تجاوز حدود حصص القرص؛
زيادة حدود الموارد (انظر setrlimit(2)
تجاوز حد الموارد RLIMIT_NPROC؛
تجاوز الحد الأقصى لعدد الطرفيات عند تخصيص الطرفية؛
تجاوز الحد الأقصى لعدد خرائط المفاتيح؛
السماح بمقاطعات تزيد عن 64 هرتز من ساعة الوقت الحقيقي؛
رفع حد msg_qbytes لطابور رسائل System V فوق الحد الموجود في /proc/sys/kernel/msgmnb (انظر msgop(2) وmsgctl(2)
السماح بتجاوز حد المورد RLIMIT_NOFILE لعدد واصفات الملفات "قيد التنفيذ" عند تمرير واصفات الملفات إلى عملية أخرى عبر مقبس نطاق يونكس (انظر unix(7)
تجاوز حد /proc/sys/fs/pipe-size-max عند ضبط سعة الأنبوب باستخدام أمر F_SETPIPE_SZ الخاص بـ fcntl(2)؛
استخدام F_SETPIPE_SZ لزيادة سعة الأنبوب فوق الحد المحدد بواسطة /proc/sys/fs/pipe-max-size؛
تجاوز حدود /proc/sys/fs/mqueue/queues_max، و/proc/sys/fs/mqueue/msg_max، و/proc/sys/fs/mqueue/msgsize_max عند إنشاء طوابير رسائل POSIX (انظر mq_overview(7)
توظيف عملية PR_SET_MM الخاصة بـ prctl(2)؛
ضبط /proc/pid/oom_score_adj لقيمة أقل من آخر قيمة ضُبطت بواسطة عملية تملك CAP_SYS_RESOURCE.
ضبط ساعة النظام (settimeofday(2)، وstime(2)، وadjtimex(2))؛ وضبط ساعة الوقت الحقيقي (العتاد).
استخدام vhangup(2)؛ وتوظيف عمليات ioctl(2) مختلفة ذات امتيازات على الطرفيات الافتراضية.
إجراء عمليات syslog(2) ذات الامتيازات. انظر syslog(2) لمعلومات حول العمليات التي تتطلب امتيازات.
عرض عناوين النواة المكشوفة عبر /proc والواجهات الأخرى عندما تكون قيمة /proc/sys/kernel/kptr_restrict هي 1. (انظر مناقشة kptr_restrict في proc(5).)
إطلاق شيء من شأنه إيقاظ النظام (ضبط مؤقتا CLOCK_REALTIME_ALARM وCLOCK_BOOTTIME_ALARM).

التطبيق السابق والحالي

يتطلب التطبيق الكامل للقدرات ما يلي:

بالنسبة لجميع العمليات ذات الامتيازات، يجب على النواة التحقق مما إذا كان الخيط يمتلك القدرة المطلوبة في مجموعته الفعالة.
يجب أن توفر النواة استدعاءات نظام تسمح بتغيير واسترجاع مجموعات قدرات الخيط.
يجب أن يدعم نظام الملفات إرفاق القدرات بملف قابل للتنفيذ، بحيث تكتسب العملية تلك القدرات عند تنفيذ الملف.

قبل لينكس 2.6.24، استُوفِي أول مطلبين فقط؛ ومنذ لينكس 2.6.24، استُوفِيت جميع المطالب الثلاثة.

ملاحظات لمطوري النواة

عند إضافة ميزة جديدة للنواة يجب أن تُحكم بواسطة قدرة (capability)، تيقظ للنقاط التالية.

الهدف من القدرات هو تقسيم صلاحيات المستخدم الخارق إلى أجزاء، بحيث إذا اختُرق برنامج يمتلك قدرة واحدة أو أكثر، فإن قدرته على إلحاق الضرر بالنظام ستكون أقل مما لو كان البرنامج نفسه يعمل بصلاحيات الجذر (root).
لديك الخيار إما بإنشاء قدرة جديدة لميزتك الجديدة، أو ربط الميزة بإحدى القدرات الموجودة حاليًا. وللحفاظ على مجموعة القدرات بحجم يمكن إدارته، يُفضل الخيار الأخير ما لم تكن هناك أسباب قاهرة لاتخاذ الخيار الأول. (هناك أيضًا حد تقني: حجم مجموعات القدرات محدود حاليًا بـ 64 بتة).
لتحديد أي قدرة موجودة قد تكون الأنسب لربطها بميزتك الجديدة، راجع قائمة القدرات أعلاه للعثور على «صومعة» (silo) تناسب ميزتك الجديدة بشكل أفضل. أحد الأساليب المتبعة هو تحديد ما إذا كانت هناك ميزات أخرى تتطلب قدرات وتُستخدم دائمًا مع الميزة الجديدة. إذا كانت الميزة الجديدة عديمة الفائدة بدون هذه الميزات الأخرى، فيجب عليك استخدام نفس قدرة الميزات الأخرى.
لا تختر CAP_SYS_ADMIN إذا كان بإمكانك تجنب ذلك! ترتبط نسبة هائلة من فحوصات القدرات الحالية بهذه القدرة (انظر القائمة الجزئية أعلاه). ويمكن تسميتها معقوليًا بـ «الجذر الجديد»، فمن ناحية تمنح نطاقًا واسعًا من الصلاحيات، ومن ناحية أخرى يعني نطاقها الواسع أنها القدرة المطلوبة من قبل العديد من البرامج ذات الامتيازات. لا تجعل المشكلة أسوأ. الميزات الجديدة الوحيدة التي يجب ربطها بـ CAP_SYS_ADMIN هي تلك التي تطابق تمامًا الاستخدامات الحالية في تلك الصومعة.
إذا قررت أنه من الضروري حقًا إنشاء قدرة جديدة لميزتك، فلا تجعلها أو تسمها كقدرة «أحادية الاستخدام». فمثلًا، إضافة القدرة النوعية جدًا CAP_SYS_PACCT كانت على الأرجح خطأً. بدلًا من ذلك، حاول تعريف وتسمية قدرتك الجديدة كصومعة أوسع يمكن أن تندرج تحتها حالات استخدام مستقبلية أخرى ذات صلة.

مجموعات قدرات الخيط (Thread)

لكل خيط مجموعات القدرات التالية التي تحتوي على صفر أو أكثر من القدرات المذكورة أعلاه:

المسموح بها (Permitted)
هذه مجموعة عليا محددة للقدرات الفعالة التي قد يتقلدها الخيط. وهي أيضًا مجموعة عليا محددة للقدرات التي يمكن إضافتها إلى المجموعة القابلة للتوريث بواسطة خيط لا يمتلك القدرة CAP_SETPCAP في مجموعته الفعالة.
إذا تخلّى خيط عن قدرة من مجموعته المسموح بها، فلا يمكنه أبدًا استعادتها (إلا إذا استدعى execve(2) لبرنامج set-user-ID-root، أو لبرنامج تمنح قدرات ملفه المرتبطة تلك القدرة).
القابلة للتوريث (Inheritable)
هذه مجموعة من القدرات التي تُحفظ عبر execve(2). تظل القدرات القابلة للتوريث قابلة للتوريث عند تنفيذ أي برنامج، وتُضاف القدرات القابلة للتوريث إلى المجموعة المسموح بها عند تنفيذ برنامج يحتوي على البتات المقابلة المضبطة في مجموعة الملف القابلة للتوريث.
نظرًا لأن القدرات القابلة للتوريث لا تُحفظ بشكل عام عبر execve(2) عند التشغيل كمستخدم غير الجذر، فإن التطبيقات التي ترغب في تشغيل برامج مساعدة بقدرات مرفوعة يجب أن تنظر في استخدام القدرات المحيطة (ambient)، الموضحة أدناه.
الفعالة (Effective)
هذه هي مجموعة القدرات التي تستخدمها النواة لإجراء فحوصات الأذونات للخيط.
المقيدة (Bounding) (لكل خيط منذ لينكس 2.6.25)
مجموعة القدرات المقيدة هي آلية يمكن استخدامها للحد من القدرات التي تُكتسب أثناء execve(2).
منذ لينكس 2.6.25، أصبحت هذه مجموعة قدرات لكل خيط. في الأنوية الأقدم، كانت مجموعة القدرات المقيدة سمة على مستوى النظام تتشاركها جميع الخيوط في الحاسوب.
لمزيد من التفاصيل، انظر مجموعة القدرات المقيدة أدناه.
المحيطة (Ambient) (منذ لينكس 4.3)
هذه مجموعة من القدرات التي تُحفظ عبر execve(2) لبرنامج غير ذي امتيازات. تلتزم مجموعة القدرات المحيطة بقاعدة ثابتة وهي أنه لا يمكن لأي قدرة أن تكون محيطة ما لم تكن مسموحًا بها وقابلة للتوريث في آن واحد.
يمكن تعديل مجموعة القدرات المحيطة مباشرة باستخدام prctl(2). وتُخفض القدرات المحيطة آليًا إذا خُفضت أي من القدرات المسموح بها أو القابلة للتوريث المقابلة لها.
تنفيذ برنامج يغير معرف المستخدم (UID) أو معرف المجموعة (GID) بسبب بتات set-user-ID أو set-group-ID، أو تنفيذ برنامج له أي قدرات ملفات مضبطة، سيؤدي إلى مسح المجموعة المحيطة. تُضاف القدرات المحيطة إلى المجموعة المسموح بها وتُعين للمجموعة الفعالة عند استدعاء execve(2). إذا أدت القدرات المحيطة إلى زيادة القدرات المسموح بها والفعالة للعملية أثناء execve(2)، فإن هذا لا يؤدي إلى تفعيل وضع التنفيذ الآمن الموصوف في ld.so(8).

يرث الابن المنشأ عبر fork(2) نسخًا من مجموعات قدرات والده. وللتفاصيل حول كيفية تأثير execve(2) على القدرات، انظر تحويل القدرات أثناء execve()‎ أدناه.

باستخدام capset(2)، قد يتلاعب الخيط بمجموعات قدراته الخاصة؛ انظر ضبط مجموعات القدرات برمجيًا أدناه.

منذ لينكس 3.2، يعرض الملف /proc/sys/kernel/cap_last_cap القيمة الرقمية لأعلى قدرة تدعمها النواة التي تعمل؛ ويمكن استخدامه لتحديد أعلى بتة يمكن ضبطها في مجموعة قدرات.

قدرات الملفات

منذ لينكس 2.6.24، تدعم النواة ربط مجموعات القدرات بملف تنفيذي باستخدام setcap(8). تُخزن مجموعات قدرات الملف في سمة ممتدة (انظر setxattr(2) و xattr(7)) تسمى security.capability. تتطلب الكتابة في هذه السمة الممتدة القدرة CAP_SETFCAP. تحدد مجموعات قدرات الملف، بالاقتران مع مجموعات قدرات الخيط، قدرات الخيط بعد execve(2).

مجموعات قدرات الملف الثلاث هي:

المسموح بها (المعروفة سابقًا باسم القسرية):
تُسمح هذه القدرات آليًا للخيط، بغض النظر عن القدرات القابلة للتوريث للخيط.
القابلة للتوريث (المعروفة سابقًا باسم المسموح بها):
تُجرى عملية AND المنطقية لهذه المجموعة مع مجموعة الخيط القابلة للتوريث لتحديد أي القدرات القابلة للتوريث ستُفعل في المجموعة المسموح بها للخيط بعد execve(2).
الفعالة:
هذه ليست مجموعة، بل مجرد بتة واحدة. إذا ضُبطت هذه البتة، فسيُرفع أثناء execve(2) جميع القدرات الجديدة المسموح بها للخيط في المجموعة الفعالة أيضًا. وإذا لم تُضبط، فلن تكون أي من القدرات الجديدة المسموح بها في المجموعة الفعالة الجديدة بعد execve(2).
تفعيل بتة قدرة الملف الفعالة يعني أن أي قدرة ملف مسموح بها أو قابلة للتوريث تتسبب في اكتساب الخيط للقدرة المسموح بها المقابلة أثناء execve(2) (انظر تحويل القدرات أثناء execve()‎ أدناه) ستكتسب أيضًا تلك القدرة في مجموعتها الفعالة. لذا، عند تعيين قدرات لملف (setcap(8)، cap_set_file(3)، cap_set_fd(3))، إذا حددنا علم الفعالية (effective flag) كمفعل لأي قدرة، فيجب أيضًا تحديد علم الفعالية كمفعل لجميع القدرات الأخرى التي فُعل لها علم المسموح به أو القابل للتوريث المقابل.

إصدارات السمات الممتدة لقدرات الملفات

للسماح بالتوسع، تدعم النواة مخططًا لترميز رقم الإصدار داخل السمة الممتدة security.capability المستخدمة لتنفيذ قدرات الملفات. أرقام الإصدارات هذه داخلية في التنفيذ، وليست مرئية مباشرة لتطبيقات فضاء المستخدم. حتى تاريخه، الإصدارات التالية مدعومة:

كان هذا هو التنفيذ الأصلي لقدرات الملفات، والذي كان يدعم أقنعة 32 بتة لقدرات الملفات.
يسمح هذا الإصدار بأقنعة قدرات ملفات بحجم 64 بتة، وكان ضروريًا مع نمو عدد القدرات المدعومة ليتجاوز 32. تستمر النواة بشفافية في دعم تنفيذ الملفات التي لها أقنعة قدرات الإصدار 1 بحجم 32 بتة، ولكن عند إضافة قدرات لملفات لم تكن تمتلك قدرات سابقًا، أو تعديل قدرات ملفات موجودة، فإنها تستخدم آليًا مخطط الإصدار 2 (أو ربما مخطط الإصدار 3، كما هو موضح أدناه).
قُدمت قدرات ملفات الإصدار 3 لدعم قدرات الملفات ذات فضاءات الأسماء (namespaced) (الموضحة أدناه).
كما هو الحال في قدرات الملفات من الإصدار 2، فإن أقنعة قدرات الإصدار 3 تكون بحجم 64 بتة. ولكن بالإضافة إلى ذلك، يُرمز معرف مستخدم الجذر لفضاء الأسماء في السمة الممتدة security.capability. (معرف مستخدم الجذر لفضاء الأسماء هو القيمة التي يقابلها معرف المستخدم 0 داخل فضاء الأسماء هذا في فضاء أسماء المستخدمين المبدئي).
صُممت قدرات الملفات من الإصدار 3 لتتعايش مع قدرات الإصدار 2؛ أي أنه في نظام لينكس حديث، قد تكون هناك بعض الملفات بقدرات من الإصدار 2 بينما تمتلك أخرى قدرات من الإصدار 3.

قبل لينكس 4.14، كان النوع الوحيد من السمات الممتدة لقدرات الملفات التي يمكن إرفاقها بملف هو سمة VFS_CAP_REVISION_2. ومنذ لينكس 4.14، يعتمد إصدار سمة security.capability الممتدة المرفقة بالملف على الظروف التي أُنشئت فيها السمة.

بدءًا من لينكس 4.14، تُنشأ سمة security.capability الممتدة آليًا كسمة من الإصدار 3 (VFS_CAP_REVISION_3) (أو تُحول إليها) إذا تحقق الشرطان التاليان:

يقبع الخيط الذي يكتب السمة في فضاء أسماء مستخدمين غير مبدئي. (بشكل أدق: يقبع الخيط في فضاء أسماء مستخدمين غير الذي وُصل منه نظام الملفات الأساسي).
يمتلك الخيط القدرة CAP_SETFCAP على فهرس (inode) الملف، مما يعني أن (أ) الخيط يمتلك القدرة CAP_SETFCAP في فضاء أسماء المستخدمين الخاص به؛ و(ب) معرف المستخدم (UID) ومعرف المجموعة (GID) لفهرس الملف لهما مقابلات في فضاء أسماء مستخدمي الكاتب.

عند إنشاء سمة security.capability ممتدة من نوع VFS_CAP_REVISION_3، يُحفظ معرف مستخدم الجذر لفضاء أسماء الخيط المنشئ في السمة الممتدة.

على النقيض من ذلك، فإن إنشاء أو تعديل سمة security.capability ممتدة من خيط ذي امتياز (CAP_SETFCAP) يقبع في فضاء الأسماء الذي وُصل منه نظام الملفات الأساسي (وهذا يعني عادةً فضاء أسماء المستخدمين المبدئي) يؤدي آليًا إلى إنشاء سمة من الإصدار 2 (VFS_CAP_REVISION_2).

لاحظ أن إنشاء سمة security.capability ممتدة من الإصدار 3 يتم آليًا. بمعنى أنه عندما يكتب تطبيق في فضاء المستخدم (setxattr(2)) سمة security.capability بتنسيق الإصدار 2، ستنشئ النواة آليًا سمة من الإصدار 3 إذا أُنشئت السمة في الظروف الموضحة أعلاه. وبالمقابل، عندما تسترجع (getxattr(2)) عملية تقبع داخل فضاء أسماء مستخدمين أُنشئ بواسطة معرف مستخدم الجذر (أو سليل لفضاء الأسماء هذا) سمة security.capability من الإصدار 3، فإن السمة المسترجعة تُبسط (آليًا) لتظهر كسمة من الإصدار 2 (أي أن القيمة المسترجعة تكون بحجم سمة الإصدار 2 ولا تتضمن معرف مستخدم الجذر). تعني هذه الترجمات الآلية أنه لا يلزم إجراء أي تغييرات على أدوات فضاء المستخدم (مثل setcap(1) و getcap(1)) لكي تُستخدم تلك الأدوات لإنشاء واسترجاع سمات security.capability من الإصدار 3.

لاحظ أن الملف يمكن أن يرتبط بسمة security.capability ممتدة إما من الإصدار 2 أو الإصدار 3، ولكن ليس كلاهما معًا: سيؤدي إنشاء أو تعديل سمة security.capability الممتدة آليًا إلى تعديل الإصدار وفقًا للظروف التي أُنشئت أو عُدلت فيها السمة.

تحويل القدرات أثناء execve()‎

أثناء execve(2)، تحسب النواة القدرات الجديدة للعملية باستخدام الخوارزمية التالية:


P'(ambient)     = (الملف ذو امتياز) ? 0 : P(ambient)
P'(permitted)   = (P(inheritable) & F(inheritable)) |

(F(permitted) & P(bounding)) | P'(ambient) P'(effective) = F(effective) ? P'(permitted) : P'(ambient) P'(inheritable) = P(inheritable) [أي بلا تغيير] P'(bounding) = P(bounding) [أي بلا تغيير]

حيث:

يرمز لقيمة مجموعة قدرات الخيط قبل execve(2)
يرمز لقيمة مجموعة قدرات الخيط بعد execve(2)
يرمز لمجموعة قدرات ملف

لاحظ التفاصيل التالية المتعلقة بقواعد تحويل القدرات المذكورة أعلاه:

مجموعة القدرات المحيطة موجودة فقط منذ لينكس 4.3. عند تحديد تحول المجموعة المحيطة أثناء execve(2)، يُعد الملف ذو الامتياز هو الملف الذي يمتلك قدرات أو يكون فيه بت set-user-ID أو set-group-ID مضبطًا.
قبل لينكس 2.6.25، كانت المجموعة المقيدة سمة على مستوى النظام تتشاركها جميع الخيوط. استُخدمت تلك القيمة العامة للنظام لحساب المجموعة المسموح بها الجديدة أثناء execve(2) بنفس الطريقة الموضحة أعلاه لـ P(bounding).

ملاحظة: أثناء تحولات القدرات الموضحة أعلاه، قد تُتجاهل قدرات الملف (تُعامل كأنها فارغة) لنفس الأسباب التي تُتجاهل فيها بتات set-user-ID و set-group-ID؛ انظر execve(2). وتُتجاهل قدرات الملفات بالمثل إذا أُقلعت النواة مع خيار no_file_caps.

ملاحظة: وفقًا للقواعد أعلاه، إذا قامت عملية بمعرفات مستخدمين غير صفرية بـ execve(2)، فسيُمسح أي قدرات موجودة في مجموعاتها المسموح بها والفعالة. وبالنسبة لمعاملة القدرات عندما تقوم عملية بمعرف مستخدم صفر بـ execve(2)، انظر القدرات وتنفيذ البرامج بواسطة الجذر أدناه.

فحص السلامة للثنائيات الغبية تجاه القدرات (capability-dumb)

الثنائي الغبي تجاه القدرات هو تطبيق وُسم ليكون له قدرات ملفات، ولكنه لم يُحول لاستخدام واجهة برمجة تطبيقات libcap(3) للتلاعب بقدراته. (بمعنى آخر، هذا برنامج set-user-ID-root تقليدي تم تبديله لاستخدام قدرات الملفات، ولكن لم يُعدل كوده ليفهم القدرات). لمثل هذه التطبيقات، تُضبط بتة قدرة الملف الفعالة، بحيث تُفعل قدرات الملف المسموح بها آليًا في المجموعة الفعالة للعملية عند تنفيذ الملف. تتعرف النواة على الملف الذي يحتوي على بتة القدرة الفعالة المضبطة كغبي تجاه القدرات لغرض الفحص الموضح هنا.

عند تنفيذ ثنائي غبي تجاه القدرات، تفحص النواة ما إذا كانت العملية قد حصلت على جميع القدرات المسموح بها التي حُددت في مجموعة الملف المسموح بها، بعد إجراء تحولات القدرات الموضحة أعلاه. (السبب المعتاد لعدم حدوث ذلك هو أن مجموعة القدرات المقيدة حجبت بعض القدرات في مجموعة الملف المسموح بها). إذا لم تحصل العملية على كامل مجموعة قدرات الملف المسموح بها، يفشل execve(2) مع الخطأ EPERM. يمنع هذا المخاطر الأمنية المحتملة التي قد تنشأ عند تنفيذ تطبيق غبي تجاه القدرات بامتيازات أقل مما يحتاج. لاحظ أنه، بحكم التعريف، لا يمكن للتطبيق نفسه التعرف على هذه المشكلة، لأنه لا يستخدم واجهة برمجة تطبيقات libcap(3).

القدرات وتنفيذ البرامج بواسطة الجذر

لمحاكاة دلالات يونكس التقليدية، تقوم النواة بمعاملة خاصة لقدرات الملفات عندما تقوم عملية بمعرف مستخدم 0 (الجذر) بتنفيذ برنامج وعند تنفيذ برنامج set-user-ID-root.

بعد إجراء أي تغييرات على المعرف الفعال للعملية التي حفزتها بتة وضع set-user-ID للثنائي -على سبيل المثال، تبديل معرف المستخدم الفعال إلى 0 (الجذر) بسبب تنفيذ برنامج set-user-ID-root- تحسب النواة مجموعات قدرات الملف كما يلي:

(1)
إذا كان معرف المستخدم الحقيقي أو الفعال للعملية هو 0 (الجذر)، فتُتجاهل مجموعتا الملف القابلة للتوريث والمسموح بها؛ وبدلًا من ذلك تُعتبر نظريًا كلها آحادًا (أي جميع القدرات مفعلة). (هناك استثناء واحد لهذا السلوك، موضح في برامج set-user-ID-root التي لها قدرات ملفات أدناه).
(2)
إذا كان معرف المستخدم الفعال للعملية هو 0 (الجذر) أو كانت بتة الملف الفعالة مفعلة في الواقع، فتُعرف بتة الملف الفعالة نظريًا بأنها واحد (مفعلة).

تُستخدم هذه القيم النظرية لمجموعات قدرات الملف كما هو موضح أعلاه لحساب تحول قدرات العملية أثناء execve(2).

وبالتالي، عندما تقوم عملية بمعرفات مستخدمين غير صفرية بـ execve(2) لبرنامج set-user-ID-root ليس له قدرات مرفقة، أو عندما تقوم عملية معرفاتها الحقيقية والفعالة صفر بـ execve(2) لبرنامج ما، يتبسط حساب القدرات المسموح بها الجديدة للعملية إلى:


P'(permitted)   = P(inheritable) | P(bounding)
P'(effective)   = P'(permitted)

ونتيجة لذلك، تكتسب العملية جميع القدرات في مجموعتي قدراتها المسموح بها والفعالة، باستثناء تلك التي حجبتها مجموعة القدرات المقيدة. (في حساب P'(permitted)، يمكن تبسيط المصطلح P'(ambient) وحذفه لأنه بحكم التعريف مجموعة جزئية مناسبة من P(inheritable)).

يمكن تعطيل المعاملات الخاصة لمعرف المستخدم 0 (الجذر) الموضحة في هذا القسم الفرعي باستخدام آلية بتات الأمان (securebits) الموضحة أدناه.

برامج set-user-ID-root التي تمتلك قدرات ملفات

هناك استثناء واحد للسلوك الموصوف في القدرات وتنفيذ البرامج بواسطة الجذر أعلاه. إذا كان (أ) الثنائي الذي يُنفذ له قدرات مرفقة و(ب) معرف المستخدم الحقيقي للعملية ليس 0 (الجذر) و(ج) معرف المستخدم الفعال للعملية هو 0 (الجذر)، فحينها تُحترم بتات قدرات الملف (أي لا تُعتبر نظريًا كلها آحادًا). الطريقة المعتادة التي يمكن أن ينشأ بها هذا الموقف هي عند تنفيذ برنامج set-UID-root يمتلك أيضًا قدرات ملفات. عند تنفيذ مثل هذا البرنامج، تكتسب العملية فقط القدرات التي يمنحها البرنامج (أي ليس كل القدرات، كما يحدث عند تنفيذ برنامج set-user-ID-root ليس له أي قدرات ملفات مرتبطة).

لاحظ أنه يمكن تعيين مجموعات قدرات فارغة لملف برنامج، وبالتالي من الممكن إنشاء برنامج set-user-ID-root يغير معرف المستخدم الفعال والمحفوظ للعملية التي تنفذ البرنامج إلى 0، ولكنه لا يمنح أي قدرات لتلك العملية.

مجموعة القدرات المقيدة

مجموعة القدرات المقيدة هي آلية أمنية يمكن استخدامها للحد من القدرات التي يمكن اكتسابها أثناء execve(2). تُستخدم المجموعة المقيدة بالطرق التالية:

أثناء execve(2)، تُجرى عملية AND المنطقية لمجموعة القدرات المقيدة مع مجموعة قدرات الملف المسموح بها، وتُعين نتيجة هذه العملية لمجموعة قدرات الخيط المسموح بها. وبذلك تضع مجموعة القدرات المقيدة حدًا للقدرات المسموح بها التي قد يمنحها ملف تنفيذي.
(منذ لينكس 2.6.25) تعمل مجموعة القدرات المقيدة كمجموعة عليا محددة للقدرات التي يمكن للخيط إضافتها إلى مجموعته القابلة للتوريث باستخدام capset(2). وهذا يعني أنه إذا لم تكن القدرة في المجموعة المقيدة، فلا يمكن للخيط إضافة هذه القدرة إلى مجموعته القابلة للتوريث، حتى لو كانت في قدراته المسموح بها، وبالتالي لا يمكن حفظ هذه القدرة في مجموعته المسموح بها عندما يستدعي execve(2) لملف يحتوي على القدرة في مجموعته القابلة للتوريث.

لاحظ أن المجموعة المقيدة تحجب قدرات الملف المسموح بها، ولكن ليس القدرات القابلة للتوريث. إذا احتفظ خيط بقدرة في مجموعته القابلة للتوريث لم تكن موجودة في مجموعته المقيدة، فيمكنه أن يكتسب تلك القدرة في مجموعته المسموح بها عن طريق تنفيذ ملف يحتوي على القدرة في مجموعته القابلة للتوريث.

اعتمادًا على إصدار النواة، تكون مجموعة القدرات المقيدة إما سمة على مستوى النظام، أو سمة لكل عملية.

مجموعة القدرات المقيدة من لينكس 2.6.25 فصاعدًا

منذ لينكس 2.6.25، أصبحت مجموعة القدرات المقيدة سمة لكل خيط. (مجموعة القدرات المقيدة على مستوى النظام الموصوفة أدناه لم تعد موجودة).

تُورث المجموعة المقيدة عند fork(2) من والد الخيط، وتُحفظ عبر execve(2).

قد يزيل خيط ما قدرات من مجموعة قدراته المقيدة باستخدام عملية PR_CAPBSET_DROP في prctl(2)، بشرط امتلاكه للقدرة CAP_SETPCAP. وبمجرد إسقاط قدرة من المجموعة المقيدة، لا يمكن استعادتها لتلك المجموعة. يمكن للخيط تحديد ما إذا كانت القدرة في مجموعته المقيدة باستخدام عملية PR_CAPBSET_READ في prctl(2).

إزالة القدرات من المجموعة المقيدة مدعوم فقط إذا كانت قدرات الملفات مجمعة (compiled) داخل النواة. قبل لينكس 2.6.33، كانت قدرات الملفات ميزة اختيارية يمكن ضبطها عبر الخيار CONFIG_SECURITY_FILE_CAPABILITIES. ومنذ لينكس 2.6.33، أُزيل خيار الضبط هذا وأصبحت قدرات الملفات دائمًا جزءًا من النواة. عندما تُجمع قدرات الملفات في النواة، تبدأ عملية init (سلف جميع العمليات) بمجموعة مقيدة كاملة. وإذا لم تُجمع قدرات الملفات في النواة، فستبدأ init بمجموعة مقيدة كاملة ناقصة القدرة CAP_SETPCAP، لأن لهذه القدرة معنى مختلفًا عند عدم وجود قدرات ملفات.

لا يؤدي حذف قدرة من مجموعة التقييد (bounding set) إلى حذفها من مجموعة التوريث الخاصة بالخيط. ومع ذلك، فإنه يمنع إعادة إضافة القدرة إلى مجموعة توريث الخيط في المستقبل.

مجموعة تقييد القدرات قبل لينكس 2.6.25

قبل إصدار لينكس 2.6.25، كانت مجموعة تقييد القدرات سمة على مستوى النظام بالكامل تؤثر على جميع الخيوط في النظام. يمكن الوصول إلى مجموعة التقييد عبر الملف /proc/sys/kernel/cap-bound. (ومما يثير الارتباك، أن معلمة قناع البتات هذه يُعبر عنها برقم عشري موقع في /proc/sys/kernel/cap-bound.)

وحده إجراء init يمكنه ضبط القدرات في مجموعة تقييد القدرات؛ وبخلاف ذلك، لا يمكن للمستخدم الخارق (وبدقة أكثر: إجراء يمتلك قدرة CAP_SYS_MODULE) إلا مسح القدرات من هذه المجموعة.

في النظام القياسي، تحجب مجموعة تقييد القدرات دائماً قدرة CAP_SETPCAP. ولإزالة هذا القيد (أمر خطر!)، يجب تعديل تعريف CAP_INIT_EFF_SET في include/linux/capability.h وإعادة بناء النواة.

أُضيفت ميزة مجموعة تقييد القدرات على مستوى النظام إلى لينكس 2.2.11.

أثر تغييرات معرف المستخدم على القدرات

للحفاظ على الدلالات التقليدية للانتقالات بين معرف المستخدم 0 وغير الصفر، تجري النواة التغييرات التالية على مجموعات قدرات الخيط عند تغيير معرفات المستخدم الحقيقية، والفعالة، والمحفوظة، ومعرف مستخدم نظام الملفات (باستخدام setuid(2) أو setresuid(2) أو ما شابه ذلك):

إذا كان واحد أو أكثر من معرفات المستخدم الحقيقية أو الفعالة أو المحفوظة قيمته 0 سابقاً، ونتج عن تغييرات المعرف أن أصبحت كل هذه المعرفات بقيمة غير صفرية، فتُمسح جميع القدرات من مجموعات القدرات المسموح بها، والفعالة، والمحيطة.
إذا غُيّر معرف المستخدم الفعال من 0 إلى قيمة غير صفرية، فتُمسح جميع القدرات من المجموعة الفعالة.
إذا غُيّر معرف المستخدم الفعال من قيمة غير صفرية إلى 0، فتُنسخ المجموعة المسموح بها إلى المجموعة الفعالة.
إذا غُيّر معرف مستخدم نظام الملفات من 0 إلى قيمة غير صفرية (انظر setfsuid(2))، فتُمسح القدرات التالية من المجموعة الفعالة: CAP_CHOWN، وCAP_DAC_OVERRIDE، وCAP_DAC_READ_SEARCH، وCAP_FOWNER، وCAP_FSETID، وCAP_LINUX_IMMUTABLE (منذ لينكس 2.6.30)، وCAP_MAC_OVERRIDE، وCAP_MKNOD (منذ لينكس 2.6.30). وإذا غُيّر معرف مستخدم نظام الملفات من قيمة غير صفرية إلى 0، فإن أيًّا من هذه القدرات المُمكّنة في المجموعة المسموح بها تُمكّن في المجموعة الفعالة.

إذا أراد خيط يمتلك القيمة 0 لواحد أو أكثر من معرفات مستخدميه منع مسح مجموعة قدراته المسموح بها عند إعادة تعيين جميع معرفاته إلى قيم غير صفرية، فيمكنه فعل ذلك باستخدام علامة securebits المسماة SECBIT_KEEP_CAPS الموضحة أدناه.

ضبط مجموعات القدرات برمجياً

يمكن للخيط استرجاع وتغيير مجموعات قدراته المسموح بها والفعالة والقابلة للتوريث باستخدام استدعاءات النظام capget(2) وcapset(2). ومع ذلك، يُفضل استخدام cap_get_proc(3) وcap_set_proc(3)، الموفرين في حزمة libcap، لهذا الغرض. تحكم القواعد التالية التغييرات على مجموعات قدرات الخيط:

إذا لم يمتلك المستدعِي قدرة CAP_SETPCAP، فيجب أن تكون مجموعة التوريث الجديدة مجموعة جزئية من مزيج مجموعتي التوريث والمسموح بها الموجودتين حالياً.
(منذ لينكس 2.6.25) يجب أن تكون مجموعة التوريث الجديدة مجموعة جزئية من مزيج مجموعة التوريث الموجودة حالياً ومجموعة تقييد القدرات.
يجب أن تكون المجموعة المسموح بها الجديدة مجموعة جزئية من المجموعة المسموح بها الموجودة حالياً (أي لا يمكن اكتساب قدرات مسموح بها لا يمتلكها الخيط حالياً).
يجب أن تكون المجموعة الفعالة الجديدة مجموعة جزئية من المجموعة المسموح بها الجديدة.

علامات securebits: إنشاء بيئة مقتصرة على القدرات

بدءاً من لينكس 2.6.26، ومع نواة مُمكن فيها قدرات الملفات، يطبق لينكس مجموعة من علامات securebits لكل خيط يمكن استخدامها لتعطيل المعالجة الخاصة للقدرات لمعرف المستخدم 0 (root). وهذه العلامات هي:

يسمح ضبط هذه العلامة للخيط الذي يمتلك واحداً أو أكثر من معرفات المستخدم 0 بالاحتفاظ بالقدرات في مجموعته المسموح بها عندما يحول جميع معرفاته إلى قيم غير صفرية. وإذا لم تُضبط هذه العلامة، فإن هذا التحويل يؤدي إلى فقدان الخيط لجميع القدرات المسموح بها. تُميَّل هذه العلامة للمسح دائماً عند execve(2).
لاحظ أنه حتى مع ضبط علامة SECBIT_KEEP_CAPS، فإن القدرات الفعالة للخيط تُمسح عندما يحول معرف مستخدمه الفعال إلى قيمة غير صفرية. ومع ذلك، إذا ضبط الخيط هذه العلامة وكان معرفه الفعال غير صفري بالفعل، ثم حول الخيط لاحقاً جميع معرفاته الأخرى إلى قيم غير صفرية، فلن تُمسح القدرات الفعالة.
يُتجاهل ضبط علامة SECBIT_KEEP_CAPS إذا كانت علامة SECBIT_NO_SETUID_FIXUP مضبوطة. (توفر العلامة الأخيرة مجموعة فائقة من أثر العلامة الأولى.)
توفر هذه العلامة نفس الوظيفة التي كانت توفرها عملية prctl(2) PR_SET_KEEPCAPS القديمة.
يؤدي ضبط هذه العلامة إلى إيقاف النواة عن تعديل مجموعات قدرات الإجراء المسموح بها، والفعالة، والمحيطة عند تبديل معرفات المستخدم الفعالة ومعرفات نظام الملفات بين قيم صفرية وغير صفرية. انظر أثر تغييرات معرف المستخدم على القدرات أعلاه.
إذا ضُبطت هذه البتة، فإن النواة لا تمنح قدرات عند تنفيذ برنامج set-user-ID-root، أو عندما يستدعي إجراء يمتلك معرف مستخدم فعال أو حقيقي قيمته 0 الدالة execve(2). (انظر القدرات وتنفيذ البرامج من قبل root أعلاه.)
يؤدي ضبط هذه العلامة إلى منع رفع القدرات المحيطة عبر عملية prctl(2) PR_CAP_AMBIENT_RAISE.

تمتلك كل علامة "أساسية" من العلامات أعلاه علامة "مغلقة" (locked) مرافقة لها. وضبط أي من العلامات "المغلقة" لا يمكن الرجوع عنه، وله أثر يتمثل في منع إجراء المزيد من التغييرات على العلامة "الأساسية" المقابلة. العلامات المغلقة هي: SECBIT_KEEP_CAPS_LOCKED، وSECBIT_NO_SETUID_FIXUP_LOCKED، وSECBIT_NOROOT_LOCKED، وSECBIT_NO_CAP_AMBIENT_RAISE_LOCKED.

يمكن تعديل واسترجاع علامات securebits باستخدام عمليتي prctl(2) PR_SET_SECUREBITS وPR_GET_SECUREBITS. وتُطلب قدرة CAP_SETPCAP لتعديل العلامات. لاحظ أن ثوابت SECBIT_* لا تتوفر إلا بعد تضمين ملف الترويسة <linux/securebits.h>.

تُورث علامات securebits بواسطة الإجراءات الابنة. وأثناء execve(2)، يُحتفظ بجميع العلامات، باستثناء SECBIT_KEEP_CAPS التي تُمسح دائماً.

يمكن للتطبيق استخدام الاستدعاء التالي ليغلق على نفسه، وعلى جميع المتحدرين منه، في بيئة تكون فيها الطريقة الوحيدة لاكتساب القدرات هي تنفيذ برنامج يمتلك قدرات ملفات مرتبطة به:


prctl(PR_SET_SECUREBITS,

/* إيقاف SECBIT_KEEP_CAPS */
SECBIT_KEEP_CAPS_LOCKED |
SECBIT_NO_SETUID_FIXUP |
SECBIT_NO_SETUID_FIXUP_LOCKED |
SECBIT_NOROOT |
SECBIT_NOROOT_LOCKED);
/* ضبط/إغلاق SECBIT_NO_CAP_AMBIENT_RAISE
ليس مطلوباً */

برامج "set-user-ID-root" لكل فضاء اسم مستخدم

إن برنامج set-user-ID الذي يطابق معرف مستخدمه المعرف الذي أنشأ فضاء اسم مستخدم سيمنح قدرات في مجموعتي الإجراء المسموح بها والفعالة عند تنفيذه بواسطة أي إجراء داخل فضاء الاسم ذلك أو أي فضاء اسم مستخدم متحدر منه.

القواعد المتعلقة بتحويل قدرات الإجراء أثناء execve(2) هي تماماً كما وُصفت في تحويل القدرات أثناء execve() و القدرات وتنفيذ البرامج من قبل root أعلاه، مع اختلاف أن "root" في القسم الفرعي الأخير هو معرف المستخدم لمنشئ فضاء اسم المستخدم.

قدرات الملفات ضمن فضاء الاسم

تربط قدرات الملفات التقليدية (أي الإصدار 2) فقط مجموعة من أقنعة القدرات بالملف التنفيذي الثنائي. وعندما ينفذ إجراء ما ملفاً ثنائياً بهذه القدرات، فإنه يكتسب القدرات المرتبطة (ضمن فضاء اسم المستخدم الخاص به) وفقاً للقواعد الموضحة في تحويل القدرات أثناء execve() أعلاه.

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

أضاف لينكس 4.14 ما يسمى بقدرات الملفات ضمن فضاء الاسم لدعم حالات الاستخدام هذه. تُسجل قدرات الملفات ضمن فضاء الاسم كسمات موسعة security.capability من الإصدار 3 (أي VFS_CAP_REVISION_3). تُنشأ هذه السمة آلياً في الظروف الموضحة في إصدارات السمات الموسعة لقدرات الملفات أعلاه. وعندما تُنشأ سمة موسعة security.capability من الإصدار 3، تسجل النواة في السمة الموسعة ليس فقط أقنعة القدرات، ولكن أيضاً معرف مستخدم الجذر لفضاء الاسم.

كما هو الحال مع الملف الثنائي الذي يمتلك قدرات ملفات VFS_CAP_REVISION_2، فإن الملف الثنائي الذي يمتلك قدرات VFS_CAP_REVISION_3 يمنح قدرات للإجراء أثناء execve(). ومع ذلك، لا تمنح القدرات إلا إذا نُفذ الملف الثنائي بواسطة إجراء يتواجد في فضاء اسم مستخدم تُرسم فيه القيمة 0 لمعرف المستخدم إلى معرف مستخدم الجذر المحفوظ في السمة الموسعة، أو عند تنفيذه بواسطة إجراء يتواجد في فضاء اسم متحدر من فضاء اسم كهذا.

التفاعل مع فضاءات أسماء المستخدمين

لمزيد من المعلومات حول التفاعل بين القدرات وفضاءات أسماء المستخدمين، انظر user_namespaces(7).

المعايير

لا توجد معايير تحكم القدرات، ولكن تطبيق قدرات لينكس يعتمد على مسودة معيار POSIX.1e المسحوبة https://archive.org/details/posix_1003.1e-990310.

ملاحظات

عند محاولة استخدام strace(1) على ملفات ثنائية تمتلك قدرات (أو ملفات ثنائية من نوع set-user-ID-root)، قد تجد الخيار -u <username> مفيداً. مثل هذا:


$ sudo strace -o trace.log -u ceci ./myprivprog

من إصدار لينكس 2.5.27 إلى لينكس 2.6.26، كانت القدرات مكوناً اختيارياً للنواة، وكان يمكن تمكينها/تعطيلها عبر خيار ضبط النواة CONFIG_SECURITY_CAPABILITIES.

يمكن استخدام الملف /proc/pid/task/TID/status لعرض مجموعات قدرات خيط ما. ويظهر الملف /proc/pid/status مجموعات قدرات الخيط الرئيس للإجراء. قبل لينكس 3.8، كانت القدرات غير الموجودة تظهر على أنها مُمكّنة (1) في هذه المجموعات. ومنذ لينكس 3.8، تظهر جميع القدرات غير الموجودة (فوق CAP_LAST_CAP) على أنها معطلة (0).

توفر حزمة libcap مجموعة من الروتينات لضبط وجلب القدرات، وهي أكثر راحة وأقل عرضة للتغيير من الواجهة التي يوفرها capset(2) وcapget(2). توفر هذه الحزمة أيضاً برامج setcap(8) وgetcap(8). يمكن العثور عليها في
https://git.kernel.org/pub/scm/libs/libcap/libcap.git/refs/.

قبل لينكس 2.6.24، ومن لينكس 2.6.24 إلى لينكس 2.6.32 إذا لم تكن قدرات الملفات مُمكّنة، كان بإمكان خيط يمتلك قدرة CAP_SETPCAP التلاعب بقدرات خيوط أخرى غير نفسه. ومع ذلك، هذا ممكن من الناحية النظرية فقط، لأنه لا يوجد خيط يمتلك CAP_SETPCAP في أي من هاتين الحالتين:

في التطبيق ما قبل الإصدار 2.6.25، كانت مجموعة تقييد القدرات على مستوى النظام، /proc/sys/kernel/cap-bound، تحجب دائماً قدرة CAP_SETPCAP، ولا يمكن تغيير ذلك دون تعديل مصدر النواة وإعادة بنائها.
إذا كانت قدرات الملفات معطلة (أي أن خيار النواة CONFIG_SECURITY_FILE_CAPABILITIES معطل)، فإن init يبدأ بقدة CAP_SETPCAP محذوفة من مجموعة التقييد الخاصة به لكل إجراء، وتُورث مجموعة التقييد هذه من قبل جميع الإجراءات الأخرى المنشأة في النظام.

انظر أيضًا

capsh(1)، وsetpriv(1)، وprctl(2)، وsetfsuid(2)، وcap_clear(3)، وcap_copy_ext(3)، وcap_from_text(3)، وcap_get_file(3)، وcap_get_proc(3)، وcap_init(3)، وcapgetp(3)، وcapsetp(3)، وlibcap(3)، وproc(5)، وcredentials(7)، وpthreads(7)، وuser_namespaces(7)، وcaptest(8)، وfilecap(8)، وgetcap(8)، وgetpcaps(8)، وnetcap(8)، وpscap(8)، وsetcap(8)

include/linux/capability.h في شجرة مصدر نواة لينكس

ترجمة

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

هذه الترجمة هي وثيقة مجانية؛ راجع رخصة جنو العامة الإصدار 3 أو ما بعده للاطلاع على شروط حقوق النشر. لا توجد أي ضمانات.

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

8 فبراير 2026 صفحات دليل لينكس 6.18