يشجع Android الشركات المصنعة للمعدات الأصلية بشدة على اختبار تطبيقات SELinux الخاصة بهم بدقة. نظرًا لأن المصنِّعين يطبقون SELinux ، يجب عليهم تطبيق السياسة الجديدة على مجموعة اختبار من الأجهزة أولاً.
بعد تطبيق سياسة جديدة ، تأكد من تشغيل SELinux في الوضع الصحيح على الجهاز بإصدار الأمر getenforce
.
هذا يطبع وضع SELinux العام: إما Enforcing أو 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
) ، فإنه يخبرك تقريبًا بما تم فعله لما يحدث. في هذه الحالة ، كان هناك شيء ما يحاول الاتصال بمقبس تدفق يونكس. -
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 Stacks
في بعض الحالات ، لا تكون المعلومات الواردة في سجل الأحداث كافية لتحديد أصل الرفض. غالبًا ما يكون من المفيد تجميع سلسلة الاستدعاء ، بما في ذلك kernel و userspace ، لفهم سبب حدوث الرفض بشكل أفضل.
تحدد النوى الحديثة نقطة تتبع تسمى avc:selinux_audited
. استخدم Android simpleperf
لتمكين نقطة التتبع هذه والتقاط سلسلة الاستدعاء.
التكوين المدعوم
- Linux kernel> = 5.10 ، ولا سيما فروع Android Common Kernel الرئيسية و android12-5.10 مدعومان . يتم دعم فرع android12-5.4 أيضًا. يمكنك استخدام
simpleperf
لتحديد ما إذا كانت نقطة التتبع محددة على جهازك:adb root && adb shell simpleperf list | grep avc:selinux_audited
. بالنسبة لإصدارات kernel الأخرى ، يمكنك اختيار تنفيذي 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
سلسلة الاستدعاء أعلاه هي نواة موحدة وسلسلة استدعاء مساحة المستخدمين. يمنحك عرضًا أفضل لتدفق الشفرة عن طريق بدء التتبع من مساحة المستخدمين على طول الطريق وصولاً إلى النواة حيث يحدث الرفض. لمزيد من المعلومات حول simpleperf
، راجع مرجع أوامر Simpleperf القابلة للتنفيذ
التحول إلى التساهل
يمكن تعطيل فرض SELinux عبر ADB على userdebug أو eng builds. للقيام بذلك ، قم أولاً بتحويل ADB إلى الجذر عن طريق تشغيل adb root
. بعد ذلك ، لتعطيل فرض SELinux ، قم بتشغيل:
adb shell setenforce 0
أو في سطر أوامر kernel (أثناء طرح الجهاز مبكرًا):
androidboot.selinux=permissive
androidboot.selinux=enforcing
أو من خلال bootconfig في Android 12:
androidboot.selinux=permissive
androidboot.selinux=enforcing
باستخدام Audit2allow
تأخذ أداة 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
مجرد نقطة انطلاق. بعد استخدام هذه العبارات ، قد تحتاج إلى تغيير المجال المصدر وتسمية الهدف ، بالإضافة إلى دمج وحدات الماكرو المناسبة ، للوصول إلى سياسة جيدة. في بعض الأحيان ، لا ينبغي أن يؤدي الرفض قيد الفحص إلى أي تغييرات في السياسة على الإطلاق ؛ بل يجب تغيير التطبيق المخالف.