يشجِّع Android المصنّعين الأصليين للأجهزة على اختبار عمليات تنفيذ SELinux بدقة. يجب أن تطبق الشركات المصنعة نظام SELinux الجديد مجموعة اختبارية من الأجهزة أولاً.
بعد تطبيق سياسة جديدة، تأكَّد من أن SELinux يعمل بالشكل الصحيح
على الجهاز من خلال إصدار الأمر getenforce
.
يؤدي ذلك إلى طباعة وضع SELinux العام: إما Enforforce أو Permissive. إلى
لتحديد وضع SELinux لكل نطاق، فيجب عليك فحص
أو تشغيل أحدث إصدار من sepolicy-analyze
باستخدام
علامة (-p
) مناسبة، موجودة في
/platform/system/sepolicy/tools/
قراءة عمليات الرفض
تحقَّق من عدم وجود أخطاء، يتم توجيهها كسجلات أحداث إلى dmesg
وlogcat
ويمكن مشاهدتها محليًا على الجهاز. الشركات المصنّعة
فحص ناتج SELinux على dmesg
على هذه الأجهزة
تحسين الإعدادات قبل الإصدار المتاح للجميع في الوضع المتساهِل والتبديل النهائي
لوضع التنفيذ. تحتوي رسائل سجلّ SELinux على avc:
وبالتالي قد
يمكن العثور عليها بسهولة باستخدام grep
. من الممكن الحصول على البيانات
سجلات الرفض من خلال تشغيل cat /proc/kmsg
أو للحصول على سجلّات الرفض
من عملية التشغيل السابقة عن طريق تشغيل
cat /sys/fs/pstore/console-ramoops
رسائل الخطأ في SELinux محدودة بمعدَّل بعد اكتمال التشغيل لتجنُّب تعرُّض الرسائل الإلكترونية للاختراق.
السجلات. للتأكّد من رؤية جميع الرسائل ذات الصلة، يمكنك إيقاف هذه الميزة.
عن طريق تشغيل adb shell auditctl -r 0
.
باستخدام هذا الإخراج، يمكن للشركات المصنعة بسهولة تحديد الوقت الذي قد تنتهك سياسة SELinux. ويمكن للشركات المصنِّعة بعد ذلك إصلاح هذا السلوك السيئ، سواء من خلال إجراء تغييرات على البرنامج أو سياسة SELinux أو كليهما.
وعلى وجه التحديد، تشير رسائل السجل هذه إلى العمليات التي ستفشل ضمن وضع الفرض والسبب وراء ذلك. يُرجى الاطّلاع على المثال أدناه:
avc: denied { connectto } for pid=2671 comm="ping" path="/dev/socket/dnsproxyd" scontext=u:r:shell:s0 tcontext=u:r:netd:s0 tclass=unix_stream_socket
فسّر هذا الناتج على النحو التالي:
- تمثّل السمة
{ connectto }
أعلاه الإجراء الذي يتم اتّخاذه. جنبًا إلى جنب معtclass
في النهاية (unix_stream_socket
)، يخبرك تقريبًا بما تم إنجازه إلى ماذا. في هذه الحالة، كان هناك جهاز يحاول الاتصال بمقبس بث في نظام التشغيل Unix. - وتخبرك السمة
scontext (u:r:shell:s0)
بالسياق الذي بدأ الإجراء. ضِمن في هذه الحالة يكون هذا شيئًا يعمل مثل الصدفة. - توضِّح لك السمة
tcontext (u:r:netd:s0)
سياق الهدف من الإجراء. ضِمن هذا الطلب هو Unix_stream_socket مملوك لشركة "netd
". - تمنحك
comm="ping"
في الجزء العلوي تلميحًا إضافيًا حول ما كان في وقت حدوث الرفض. في هذه الحالة، يعد تلميحًا جيدًا.
مثال آخر:
adb shell su root dmesg | grep 'avc: '
جهاز إخراج الصوت:
<5> type=1400 audit: avc: denied { read write } for pid=177 comm="rmt_storage" name="mem" dev="tmpfs" ino=6004 scontext=u:r:rmt:s0 tcontext=u:object_r:kmem_device:s0 tclass=chr_file
وفي ما يلي العناصر الأساسية لهذا الرفض:
- الإجراء - الإجراء الذي تمت محاولة تنفيذه محدد بين قوسين،
read write
أوsetenforce
. - المُنفِّذ - يمثل إدخال
scontext
(سياق المصدر) الممثل، وهو في هذه الحالة البرنامج الخفيrmt_storage
. - كائن - يمثل إدخال
tcontext
(السياق المستهدف) الكائن الذي يتم العمل عليه، وهو في هذه الحالة kmem. - النتيجة - يشير إدخال
tclass
(الفئة المستهدفة) إلى النوع للكائنات قيد الإجراء، وهي في هذه الحالةchr_file
(جهاز حرف).
نسخ المستخدم وحزم Kernel المكدسة
في بعض الحالات، لا تكون المعلومات الواردة في سجلّ الأحداث كافية لتحديد أصل الرفض. غالبًا ما يكون من المفيد جمع سلسلة الاتصال، بما في ذلك النواة kernel مساحة المستخدم، لفهم سبب حدوث الرفض بشكل أفضل.
تُحدِّد النواة الأخيرة نقطة تتبُّع تُسمى avc:selinux_audited
. استخدام Android
simpleperf
لتفعيل نقطة التتبُّع هذه وتسجيل سلسلة الاتصال.
الإعدادات المتوافقة
- نواة Linux >= 5.10، على وجه الخصوص فروع Android Common Kernel
Mainline
أو
android12-5.10
android12-5.4
الفرع أيضًا. يمكنك استخدام
simpleperf
لتحديد ما إذا كانت نقطة التتبّع محدد على جهازك:adb root && adb shell simpleperf list | grep avc:selinux_audited
بالنسبة إلى إصدارات النواة الأخرى، يمكنك اختيار الالتزامات dd81662 أو 30969bc. - ينبغي أن يكون من الممكن إعادة إنتاج الحدث الذي تصححه. أحداث وقت التشغيل ليست باستخدام Simpleperf؛ ومع ذلك، قد يظل بإمكانك إعادة تشغيل الخدمة لبدء الحدث.
جارٍ تسجيل سلسلة الاتصال
الخطوة الأولى هي تسجيل الحدث باستخدام simpleperf record
:
adb shell -t "cd /data/local/tmp && su root simpleperf record -a -g -e avc:selinux_audited"
ومن ثم، يجب تشغيل الحدث الذي تسبب في الرفض. بعد ذلك، يجب أن
التوقف. في هذا المثال، باستخدام Ctrl-c
، كان يجب أن يكون قد تم أخذ العيّنة:
^Csimpleperf I cmd_record.cpp:751] Samples recorded: 1. Samples lost: 0.
أخيرًا، يمكن استخدام simpleperf report
لفحص تتبُّع تسلسل استدعاء الدوال البرمجية الذي تم التقاطه.
على سبيل المثال:
adb shell -t "cd /data/local/tmp && su root simpleperf report -g --full-callgraph" [...] Children Self Command Pid Tid Shared Object Symbol 100.00% 0.00% dmesg 3318 3318 /apex/com.android.runtime/lib64/bionic/libc.so __libc_init | -- __libc_init | -- main toybox_main toy_exec_which dmesg_main klogctl entry_SYSCALL_64_after_hwframe do_syscall_64 __x64_sys_syslog do_syslog selinux_syslog slow_avc_audit common_lsm_audit avc_audit_post_callback avc_audit_post_callback
سلسلة الاتصال المذكورة أعلاه هي نواة موحَّدة وسلسلة مكالمات userspace. فهو يمنحك تجربة أفضل
لتدفق الرمز عن طريق بدء التتبع من مساحة المستخدم وصولاً إلى النواة (النواة) حيث
حدوث الرفض. لمزيد من المعلومات عن simpleperf
، يمكنك الاطّلاع على
مرجع أوامر Simpleperf التنفيذية
التبديل إلى متساهل
يمكن إيقاف فرض SELinux عبر ADB على إصدارات userdebug أو eng. لإجراء ذلك،
أولاً تبديل ADB إلى الجذر عن طريق تشغيل adb root
. بعد ذلك، لتعطيل SELinux
التنفيذ، قم بتشغيل:
adb shell setenforce 0
أو في سطر أوامر النواة (أثناء التشغيل المبكر للجهاز):
androidboot.selinux=permissive
androidboot.selinux=enforcing
أو من خلال إعدادات التشغيل في Android 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
استخدام التدقيق2allow
تستخدم الأداة audit2allow
عمليات رفض dmesg
وتحولها إلى بيانات سياسة SELinux مقابلة. وعلى هذا النحو، يمكن أن
تعمل على تسريع تطوير SELinux بشكل كبير.
لاستخدامها، شغِّل:
adb pull /sys/fs/selinux/policy
adb logcat -b events -d | audit2allow -p policy
ومع ذلك، يجب توخي الحذر لفحص كل إضافة محتملة
وتتجاوز الأذونات. على سبيل المثال، يؤدي إطعام audit2allow
يؤدي رفض rmt_storage
الذي تم عرضه سابقًا إلى ما يلي:
بيان سياسة SELinux المقترح:
#============= shell ============== allow shell kernel:security setenforce; #============= rmt ============== allow rmt kmem_device:chr_file { read write };
وهذا من شأنه أن يمنح rmt
القدرة على كتابة ذاكرة kernel،
تمامًا. غالبًا ما تكون عبارات audit2allow
فقط
نقطة البداية. بعد استخدام هذه العبارات، قد تحتاج إلى تغيير
ونطاق المصدر وتصنيف الهدف، بالإضافة إلى دمج
وحدات الماكرو، للوصول إلى سياسة جيدة. في بعض الأحيان يجب أن يكون الإنكار الذي يتم فحصه
ألا تؤدّي إلى أيّ تغييرات في السياسة على الإطلاق بل يعتمد التطبيق المسيء
بتغييره.