سازگاری سیاست

این مقاله توضیح می‌دهد که Android چگونه مشکلات سازگاری خط‌مشی را با OTAهای پلتفرم مدیریت می‌کند، جایی که تنظیمات SELinux پلتفرم جدید ممکن است با تنظیمات SELinux فروشنده قدیمی متفاوت باشد.

طراحی خط مشی SELinux مبتنی بر سه گانه، تمایز دودویی بین خط مشی پلت فرم و فروشنده را در نظر می گیرد. اگر پارتیشن‌های فروشنده وابستگی‌هایی مانند platform < vendor < oem ایجاد کنند، این طرح پیچیده‌تر می‌شود.

در اندروید 8.0 و بالاتر، سیاست جهانی SELinux به دو بخش خصوصی و عمومی تقسیم می شود. مؤلفه‌های عمومی شامل خط‌مشی و زیرساخت‌های مرتبط هستند که تضمین می‌شوند برای نسخه پلتفرم در دسترس هستند. این خط‌مشی در معرض نویسندگان خط‌مشی فروشنده قرار می‌گیرد تا فروشندگان بتوانند یک فایل خط‌مشی فروشنده بسازند، که وقتی با خط‌مشی ارائه‌شده توسط پلتفرم ترکیب شود، منجر به یک خط‌مشی کاملاً کاربردی برای دستگاه می‌شود.

  • برای نسخه‌سازی، خط‌مشی عمومی پلتفرم صادر شده به‌عنوان ویژگی نوشته می‌شود.
  • برای سهولت در نوشتن خط مشی، انواع صادر شده به عنوان بخشی از فرآیند ساخت خط مشی به ویژگی های نسخه شده تبدیل می شوند. انواع عمومی همچنین ممکن است مستقیماً در تصمیمات برچسب‌گذاری ارائه شده توسط فایل‌های زمینه فروشنده استفاده شوند.

Android یک نقشه بین انواع بتن صادر شده در خط مشی پلت فرم و ویژگی های نسخه شده مربوطه برای هر نسخه پلت فرم را حفظ می کند . این تضمین می کند که وقتی اشیا با یک نوع برچسب گذاری می شوند، رفتار تضمین شده توسط خط مشی عمومی پلت فرم در نسخه قبلی را نقض نمی کند. این نگاشت با به روز نگه داشتن یک فایل نقشه برداری برای هر نسخه پلتفرم ، که اطلاعات عضویت ویژگی را برای هر نوع صادر شده در خط مشی عمومی حفظ می کند، حفظ می شود.

مالکیت اشیا و برچسب گذاری

هنگام سفارشی‌سازی خط‌مشی در Android نسخه 8.0 و بالاتر، مالکیت باید به وضوح برای هر شیء تعریف شود تا خط‌مشی پلت فرم و فروشنده جدا بماند. به عنوان مثال، اگر فروشنده /dev/foo و پلتفرم سپس /dev/foo در OTA بعدی برچسب گذاری کند، رفتار نامشخصی وجود خواهد داشت. برای SELinux، این به عنوان یک برخورد برچسب نشان می دهد. گره دستگاه می تواند تنها یک برچسب داشته باشد که به هر برچسبی که آخرین بار اعمال می شود، حل می شود. در نتیجه:

  • فرآیندهایی که نیاز به دسترسی به برچسب ناموفق اعمال شده دارند، دسترسی به منبع را از دست خواهند داد.
  • فرآیندهایی که به فایل دسترسی پیدا می کنند ممکن است به دلیل ایجاد گره دستگاه اشتباه شکسته شوند.

ویژگی‌های سیستم همچنین دارای پتانسیل نام‌گذاری برخوردهایی هستند که می‌توانند منجر به رفتار نامشخص در سیستم شوند (و همچنین برای برچسب‌گذاری SELinux). برخورد بین برچسب‌های پلتفرم و فروشنده می‌تواند برای هر شیئی که دارای برچسب SELinux باشد، از جمله ویژگی‌ها، سرویس‌ها، فرآیندها، فایل‌ها و سوکت‌ها رخ دهد. برای جلوگیری از این مسائل، مالکیت این اشیاء را به وضوح تعریف کنید.

علاوه بر برخورد برچسب‌ها، نام‌های نوع/ویژگی SELinux نیز ممکن است با هم برخورد کنند. برخورد نام نوع/ویژگی همیشه منجر به خطای کامپایلر خط مشی می شود.

فاصله نام تایپ/ویژگی

SELinux اجازه چند اعلان از یک نوع/ویژگی را نمی دهد. خط‌مشی با اعلان‌های تکراری در تدوین ناموفق خواهد بود. برای جلوگیری از برخورد نام نوع و صفت، همه اعلان‌های فروشنده باید با فضای نام np_ شروع شوند.

type foo, domain; → type np_foo, domain;

مالکیت دارایی سیستم و برچسب گذاری فرآیند

اجتناب از برخورد برچسب‌ها با استفاده از فضاهای نام ویژگی بهتر حل می‌شود. برای شناسایی آسان ویژگی‌های پلتفرم و جلوگیری از تداخل نام هنگام تغییر نام یا افزودن ویژگی‌های پلتفرم صادر شده، مطمئن شوید که همه ویژگی‌های فروشنده پیشوندهای خاص خود را دارند:

نوع ملک پیشوندهای قابل قبول
خواص کنترلی ctl.vendor.
ctl.start$vendor.
ctl.stop$vendor.
init.svc.vendor.
قابل خواندن و نوشتن vendor.
فقط خواندنی ro.vendor.
ro.boot.
ro.hardware.
مداوم persist.vendor.

فروشندگان می توانند به استفاده از ro.boot.* (که از cmdline هسته می آید) و ro.hardware.* (یک ویژگی واضح مرتبط با سخت افزار) ادامه دهند.

تمام سرویس های فروشنده در فایل های init rc باید دارای vendor. برای سرویس های موجود در فایل های init rc پارتیشن های غیر سیستمی. قوانین مشابهی برای برچسب های SELinux برای ویژگی های فروشنده ( vendor_ برای ویژگی های فروشنده) اعمال می شود.

مالکیت فایل

جلوگیری از برخورد برای فایل‌ها چالش برانگیز است زیرا پلتفرم و سیاست فروشنده هر دو معمولاً برچسب‌هایی را برای همه سیستم‌های فایل ارائه می‌کنند. بر خلاف نامگذاری نوع، فاصله نام فایل ها عملی نیست زیرا بسیاری از آنها توسط هسته ایجاد می شوند. برای جلوگیری از این برخوردها، راهنمای نامگذاری فایل سیستم ها را در این بخش دنبال کنید. برای اندروید 8.0، اینها توصیه هایی بدون اعمال فنی هستند. در آینده، این توصیه‌ها توسط مجموعه تست فروشنده (VTS) اعمال خواهند شد.

سیستم (/سیستم)

فقط تصویر سیستم باید برچسب‌هایی را برای اجزای /system از طریق file_contexts ، service_contexts و غیره ارائه کند. اگر برچسب‌هایی برای اجزای /system در سیاست /vendor اضافه شود، ممکن است به‌روزرسانی OTA فقط برای چارچوب امکان‌پذیر نباشد.

فروشنده (/فروشنده)

خط‌مشی AOSP SELinux قبلاً قسمت‌هایی از پارتیشن vendor را که پلتفرم با آن تعامل دارد برچسب‌گذاری می‌کند، که نوشتن قوانین SELinux را برای فرآیندهای پلتفرم قادر می‌سازد تا بتوانند صحبت کنند و/یا به بخش‌هایی از پارتیشن vendor دسترسی داشته باشند. مثال ها:

/vendor برچسب ارائه شده توسط پلتفرم فرآیندهای پلت فرم بسته به برچسب
/vendor(/. * )? vendor_file همه کلاینت های HAL در فریم ورک، ueventd و غیره.
/vendor/framework(/. * )? vendor_framework_file dex2oat ، appdomain و غیره
/vendor/app(/. * )? vendor_app_file dex2oat ، installd ، idmap و غیره.
/vendor/overlay(/. * ) vendor_overlay_file system_server ، zygote ، idmap و غیره

در نتیجه، هنگام برچسب زدن فایل‌های اضافی در پارتیشن vendor ، قوانین خاصی باید دنبال شوند (از طریق neverallows اجرا می‌شوند):

  • vendor_file باید برچسب پیش‌فرض برای همه فایل‌های پارتیشن vendor باشد. خط مشی پلتفرم به این نیاز دارد تا به پیاده سازی های HAL از طریق عبور دسترسی داشته باشد.
  • همه exec_types جدید اضافه شده در پارتیشن vendor از طریق فروشنده SEPolicy باید ویژگی vendor_file_type داشته باشند. این از طریق neverallows اجرا می شود.
  • برای جلوگیری از تداخل با به‌روزرسانی‌های پلتفرم/چارچوب آینده، از برچسب‌گذاری فایل‌های غیر از exec_types در پارتیشن vendor خودداری کنید.
  • همه وابستگی‌های کتابخانه برای HAL‌های فرآیندی شناسایی‌شده توسط AOSP باید به‌عنوان same_process_hal_file.

Procfs (/proc)

فایل‌های موجود در /proc را می‌توان تنها با استفاده از برچسب genfscon برچسب‌گذاری کرد. در Android 7.0، هم پلتفرم و هم خط‌مشی فروشنده از genfscon برای برچسب‌گذاری فایل‌ها در procfs استفاده می‌کردند.

توصیه: فقط برچسب‌های خط مشی پلتفرم /proc . اگر فرآیندهای vendor نیاز به دسترسی به فایل‌هایی در /proc دارند که در حال حاضر با برچسب پیش‌فرض ( proc ) برچسب‌گذاری شده‌اند، خط‌مشی فروشنده نباید به طور صریح آنها را برچسب‌گذاری کند و در عوض باید از نوع proc عمومی برای افزودن قوانین برای دامنه‌های فروشنده استفاده کند. این به به‌روزرسانی‌های پلتفرم اجازه می‌دهد تا رابط‌های هسته آینده را که از طریق procfs در معرض دید قرار می‌گیرند، تطبیق دهد و آنها را به صراحت در صورت نیاز برچسب‌گذاری کند.

اشکال زدایی (/sys/kernel/debug)

Debugfs می توان هم در file_contexts و هم در genfscon برچسب گذاری کرد. در اندروید 7.0 تا اندروید 10، هم پلتفرم و هم برچسب فروشنده debugfs .

در اندروید 11، debugfs قابل دسترسی نیست یا روی دستگاه های تولیدی نصب می شود. سازندگان دستگاه باید debugfs حذف کنند.

Tracefs (/sys/kernel/debug/tracing)

Tracefs می توان هم در file_contexts و هم در genfscon برچسب گذاری کرد. در Android 7.0، فقط پلتفرم tracefs برچسب گذاری می کند.

توصیه: فقط پلتفرم می‌تواند tracefs برچسب‌گذاری کند.

Sysfs (/sys)

فایل‌های موجود در /sys ممکن است با استفاده از file_contexts و genfscon برچسب‌گذاری شوند. در Android 7.0، هم پلتفرم و هم فروشنده از file_contexts و genfscon برای برچسب زدن فایل‌ها در sysfs استفاده می‌کنند.

توصیه: پلتفرم ممکن است گره‌های sysfs را که مختص دستگاه نیستند برچسب‌گذاری کند. در غیر این صورت، فقط فروشنده می تواند فایل ها را برچسب گذاری کند.

tmpfs (/dev)

فایل‌های موجود در /dev ممکن است در file_contexts برچسب‌گذاری شوند. در Android 7.0، فایل‌های برچسب پلتفرم و فروشنده در اینجا هستند.

توصیه: فروشنده ممکن است فقط فایل‌ها را در /dev/vendor برچسب بزند (به عنوان مثال، /dev/vendor/foo ، /dev/vendor/socket/bar ).

Rootfs (/)

فایل های موجود در / ممکن است در file_contexts برچسب گذاری شوند. در Android 7.0، فایل‌های برچسب پلتفرم و فروشنده در اینجا هستند.

توصیه: فقط سیستم می‌تواند فایل‌ها را در / برچسب‌گذاری کند.

داده (/داده)

داده ها از طریق ترکیبی از file_contexts و seapp_contexts برچسب گذاری می شوند.

توصیه: برچسب‌گذاری فروشنده خارج از /data/vendor را ممنوع کنید. فقط پلتفرم می‌تواند سایر بخش‌های /data را برچسب‌گذاری کند.

ویژگی های سازگاری

خط مشی SELinux یک تعامل بین انواع منبع و هدف برای کلاس‌ها و مجوزهای شی خاص است. هر شی (فرآیندها، فایل‌ها و غیره) تحت تأثیر سیاست SELinux ممکن است فقط یک نوع داشته باشد، اما آن نوع ممکن است چندین ویژگی داشته باشد.

سیاست بیشتر بر اساس انواع موجود نوشته شده است:

allow source_type target_type:target_class permission(s);

این کار به این دلیل کار می کند که خط مشی با آگاهی از همه نوع نوشته شده است. با این حال، اگر خط‌مشی فروشنده و خط‌مشی پلت فرم از انواع خاصی استفاده می‌کند و برچسب یک شی خاص فقط در یکی از آن خط‌مشی‌ها تغییر می‌کند، دیگری ممکن است حاوی خط‌مشی باشد که قبلاً به آن اعتماد کرده بود یا دسترسی را از دست داده است. مثلا:

File_contexts:
/sys/A   u:object_r:sysfs:s0
Platform: allow p_domain sysfs:class perm;
Vendor: allow v_domain sysfs:class perm;

قابل تغییر به:

File_contexts:
/sys/A   u:object_r:sysfs_A:s0

اگرچه خط مشی فروشنده یکسان باقی می ماند، v_domain به دلیل عدم وجود خط مشی برای نوع جدید sysfs_A ، دسترسی خود را از دست می دهد.

با تعریف یک خط مشی بر حسب ویژگی ها، می توانیم به شی زیربنایی نوعی بدهیم که دارای ویژگی مربوط به خط مشی هم برای پلتفرم و هم برای کد فروشنده باشد. این را می توان برای همه انواع انجام داد تا به طور مؤثر یک خط مشی ویژگی ایجاد شود که در آن انواع بتن هرگز استفاده نمی شود. در عمل، این فقط برای بخش‌هایی از خط‌مشی که بین پلتفرم و فروشنده همپوشانی دارند، که به‌عنوان خط‌مشی عمومی پلتفرمی که به‌عنوان بخشی از خط‌مشی فروشنده ایجاد می‌شود، تعریف و ارائه می‌شوند، لازم است.

تعریف خط مشی عمومی به عنوان ویژگی های نسخه شده دو هدف سازگاری خط مشی را برآورده می کند:

  • اطمینان حاصل کنید که کد فروشنده پس از به‌روزرسانی پلتفرم به کار خود ادامه می‌دهد . با افزودن ویژگی‌ها به انواع بتن برای اشیاء مربوط به مواردی که کد فروشنده بر آن‌ها تکیه دارد و دسترسی را حفظ می‌کند، به دست می‌آید.
  • قابلیت منسوخ کردن سیاست با مشخص کردن واضح مجموعه‌های خط‌مشی به ویژگی‌هایی که می‌توانند به محض اینکه نسخه‌ای که با آن مطابقت دارند دیگر پشتیبانی نشود حذف شوند، به دست می‌آید. توسعه می‌تواند در پلتفرم ادامه یابد، با دانستن اینکه خط‌مشی قدیمی همچنان در خط‌مشی فروشنده وجود دارد و در صورت ارتقاء آن به‌طور خودکار حذف می‌شود.

قابلیت نوشتن خط مشی

برای دستیابی به هدف عدم نیاز به دانش تغییرات نسخه خاص برای توسعه خط مشی، Android 8.0 شامل نقشه برداری بین انواع خط مشی عمومی پلت فرم و ویژگی های آنها است. نوع foo به ویژگی foo_v N نگاشت شده است، جایی که N نسخه مورد نظر است. vN مربوط به متغیر ساخت PLATFORM_SEPOLICY_VERSION است و به شکل MM.NN است، که در آن MM مربوط به شماره SDK پلتفرم است و NN یک نسخه خاص پلت فرم است.

ویژگی‌ها در خط‌مشی عمومی نسخه‌بندی نشده‌اند، بلکه بیشتر به‌عنوان یک API وجود دارند که پلتفرم و خط‌مشی فروشنده می‌توانند روی آن ایجاد کنند تا رابط بین دو پارتیشن پایدار بماند. هم نویسندگان خط مشی پلت فرم و هم فروشنده می توانند به نوشتن خط مشی همانطور که امروز نوشته می شود ادامه دهند.

خط مشی عمومی پلتفرم به عنوان allow source_foo target_bar: class perm ; به عنوان بخشی از سیاست فروشنده گنجانده شده است. در طول کامپایل (که شامل نسخه مربوطه می‌شود) به خط‌مشی تبدیل می‌شود که به بخش فروشنده دستگاه می‌رود (نشان داده شده در زبان میانی رایج تغییر یافته (CIL)):

 (allow source_foo_vN target_bar_vN (class (perm)))

از آنجایی که سیاست فروشنده هرگز جلوتر از پلتفرم نیست، نباید نگران نسخه های قبلی باشد. با این حال، خط‌مشی پلتفرم باید بداند خط‌مشی فروشنده چقدر عقب است، ویژگی‌هایی را در انواع آن لحاظ کند و خط‌مشی مربوط به ویژگی‌های نسخه‌شده را تنظیم کند.

سیاست متفاوت است

ایجاد خودکار ویژگی ها با افزودن _v N به انتهای هر نوع، بدون نگاشت ویژگی ها به انواع در بین تفاوت های نسخه، کاری انجام نمی دهد. اندروید یک نگاشت بین نسخه ها برای ویژگی ها و یک نگاشت انواع به آن ویژگی ها را حفظ می کند. این کار در فایل های نگاشت فوق با عباراتی مانند (CIL) انجام می شود:

(typeattributeset foo_vN (foo))

ارتقاء پلتفرم

بخش زیر سناریوهای ارتقاء پلتفرم را شرح می دهد.

انواع مشابه

این سناریو زمانی اتفاق می‌افتد که یک شی برچسب‌ها را در نسخه‌های خط‌مشی تغییر نمی‌دهد. این برای انواع منبع و هدف یکسان است و با /dev/binder قابل مشاهده است که در همه نسخه‌ها برچسب binder_device دارد. در خط مشی تغییر یافته به صورت زیر نمایش داده می شود:

binder_device_v1 … binder_device_vN

هنگام ارتقاء از v1v2 ، خط مشی پلتفرم باید شامل موارد زیر باشد:

type binder_device; -> (type binder_device) (in CIL)

در فایل نگاشت v1 (CIL):

(typeattributeset binder_device_v1 (binder_device))

در فایل نگاشت v2 (CIL):

(typeattributeset binder_device_v2 (binder_device))

در خط مشی فروشنده v1 (CIL):

(typeattribute binder_device_v1)
(allow binder_device_v1 …)

در خط مشی فروشنده v2 (CIL):

(typeattribute binder_device_v2)
(allow binder_device_v2 …)
انواع جدید

این سناریو زمانی اتفاق می‌افتد که پلتفرم نوع جدیدی را اضافه کرده باشد، که می‌تواند هنگام افزودن ویژگی‌های جدید یا در حین سخت‌سازی سیاست اتفاق بیفتد.

  • خصوصیت جدید . هنگامی که نوع، شیئی را برچسب گذاری می کند که قبلاً وجود نداشته است (مانند یک فرآیند سرویس جدید)، کد فروشنده قبلاً مستقیماً با آن تعامل نداشته است، بنابراین هیچ خط مشی مربوطه وجود ندارد. ویژگی جدید مربوط به نوع در نسخه قبلی دارای ویژگی نیست، و بنابراین نیازی به ورودی در فایل نقشه برداری که آن نسخه را هدف قرار می دهد نخواهد بود.
  • سخت شدن سیاست . وقتی نوع نشان دهنده سخت شدن خط مشی است، ویژگی نوع جدید باید به زنجیره ای از ویژگی های مربوط به قبلی مرتبط شود (مشابه با مثال قبلی که /sys/A از sysfs به sysfs_A تغییر داد). کد فروشنده متکی به قاعده‌ای است که دسترسی به sysfs را امکان‌پذیر می‌کند و باید آن قانون را به عنوان یک ویژگی از نوع جدید درج کند.

هنگام ارتقاء از v1v2 ، خط مشی پلتفرم باید شامل موارد زیر باشد:

type sysfs_A; -> (type sysfs_A) (in CIL)
type sysfs; (type sysfs) (in CIL)

در فایل نگاشت v1 (CIL):

(typeattributeset sysfs_v1 (sysfs sysfs_A))

در فایل نگاشت v2 (CIL):

(typeattributeset sysfs_v2 (sysfs))
(typeattributeset sysfs_A_v2 (sysfs_A))

در خط مشی فروشنده v1 (CIL):

(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

در خط مشی فروشنده v2 (CIL):

(typeattribute sysfs_A_v2)
(allow … sysfs_A_v2 …)
(typeattribute sysfs_v2)
(allow … sysfs_v2 …)
انواع حذف شده

این سناریو (نادر) زمانی رخ می‌دهد که یک نوع حذف شود، که می‌تواند زمانی اتفاق بیفتد که شی زیرین:

  • باقی می ماند اما برچسب متفاوتی می گیرد.
  • توسط پلت فرم حذف می شود.

در طول شل کردن خط مشی، یک نوع حذف می‌شود و به شی برچسب‌گذاری شده با آن نوع، یک برچسب متفاوت و از قبل موجود داده می‌شود. این نشان‌دهنده ادغام نگاشت ویژگی‌ها است: کد فروشنده هنوز باید بتواند به شی زیربنایی با ویژگی‌ای که قبلاً داشت، دسترسی داشته باشد، اما بقیه سیستم اکنون باید بتوانند با ویژگی جدید خود به آن دسترسی داشته باشند.

اگر مشخصه ای که به آن تغییر داده شده است جدید باشد، برچسب گذاری مجدد مانند مورد نوع جدید است، با این تفاوت که وقتی از یک برچسب موجود استفاده می شود، افزودن ویژگی قدیمی نوع جدید باعث می شود اشیاء دیگری نیز با این نوع برچسب گذاری شوند. تازه در دسترس بودن این اساساً کاری است که توسط پلتفرم انجام می شود و به عنوان یک معامله قابل قبول برای حفظ سازگاری تلقی می شود.

(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

نمونه نسخه 1: انواع در حال جمع شدن (حذف sysfs_A)

هنگام ارتقاء از v1v2 ، خط مشی پلتفرم باید شامل موارد زیر باشد:

type sysfs; (type sysfs) (in CIL)

در فایل نگاشت v1 (CIL):

(typeattributeset sysfs_v1 (sysfs))
(type sysfs_A) # in case vendors used the sysfs_A label on objects
(typeattributeset sysfs_A_v1 (sysfs sysfs_A))

در فایل نگاشت v2 (CIL):

(typeattributeset sysfs_v2 (sysfs))

در خط مشی فروشنده v1 (CIL):

(typeattribute sysfs_A_v1)
(allow … sysfs_A_v1 …)
(typeattribute sysfs_v1)
(allow … sysfs_v1 …)

در خط مشی فروشنده v2 (CIL):

(typeattribute sysfs_v2)
(allow … sysfs_v2 …)

نمونه نسخه 2: حذف کامل (نوع foo)

هنگام ارتقاء از v1v2 ، خط مشی پلتفرم باید شامل موارد زیر باشد:

# nothing - we got rid of the type

در فایل نگاشت v1 (CIL):

(type foo) #needed in case vendors used the foo label on objects
(typeattributeset foo_v1 (foo))

در فایل نگاشت v2 (CIL):

# nothing - get rid of it

در خط مشی فروشنده v1 (CIL):

(typeattribute foo_v1)
(allow foo …)
(typeattribute sysfs_v1)
(allow sysfs_v1 …)

در خط مشی فروشنده v2 (CIL):

(typeattribute sysfs_v2)
(allow sysfs_v2 …)
کلاس/مجوزهای جدید

این سناریو زمانی اتفاق می‌افتد که ارتقاء پلتفرم مؤلفه‌های سیاست جدیدی را معرفی می‌کند که در نسخه‌های قبلی وجود ندارند. به عنوان مثال، زمانی که Android مدیر شی servicemanager اضافه کرد که مجوزهای افزودن، یافتن و لیست را ایجاد می کرد، شیاطین فروشنده که می خواستند با servicemanager ثبت نام کنند به مجوزهایی نیاز داشتند که در دسترس نبود. در Android 8.0، فقط خط‌مشی پلتفرم ممکن است کلاس‌ها و مجوزهای جدیدی اضافه کند.

برای اجازه دادن به همه دامنه‌هایی که می‌توانستند توسط خط‌مشی فروشنده ایجاد یا گسترش یافته باشند تا از کلاس جدید بدون مانع استفاده کنند، خط‌مشی پلتفرم باید شامل قانون مشابهی باشد:

allow {domain -coredomain} *:new_class perm;

حتی ممکن است به خط مشی اجازه دسترسی برای همه انواع رابط (خط مشی عمومی) نیاز داشته باشد تا مطمئن شوید که تصویر فروشنده دسترسی پیدا می کند. اگر این منجر به سیاست امنیتی غیرقابل قبولی شود (همانطور که ممکن است با تغییرات مدیر سرویس باشد)، ممکن است به طور بالقوه ارتقاء فروشنده اجباری شود.

کلاس/مجوزها حذف شد

این سناریو زمانی اتفاق می‌افتد که یک مدیر شی حذف می‌شود (مانند مدیر شی ZygoteConnection ) و نباید مشکلی ایجاد کند. کلاس مدیر شی و مجوزها می توانند در خط مشی تعریف شده باقی بمانند تا زمانی که نسخه فروشنده دیگر از آن استفاده نکند. این کار با افزودن تعاریف به فایل نگاشت مربوطه انجام می شود.

سفارشی سازی فروشنده برای انواع جدید/برچسب شده

انواع فروشنده جدید هسته اصلی توسعه سیاست فروشنده هستند زیرا برای توصیف فرآیندهای جدید، باینری ها، دستگاه ها، زیرسیستم ها و داده های ذخیره شده مورد نیاز هستند. به این ترتیب، اجازه ایجاد انواع تعریف شده توسط فروشنده ضروری است.

از آنجایی که خط‌مشی فروشنده همیشه قدیمی‌ترین خط‌مشی دستگاه است، نیازی به تبدیل خودکار همه انواع فروشنده به ویژگی‌های موجود در خط‌مشی وجود ندارد. پلتفرم به هیچ چیزی که در خط مشی فروشنده برچسب گذاری شده است متکی نیست زیرا پلتفرم از آن اطلاعی ندارد. با این حال، پلتفرم ویژگی‌ها و انواع عمومی را که برای تعامل با اشیاء برچسب‌گذاری شده با این انواع استفاده می‌کند (مانند domain ، sysfs_type و غیره) ارائه می‌کند. برای اینکه پلتفرم به تعامل صحیح با این اشیاء ادامه دهد، ویژگی ها و انواع باید به طور مناسب اعمال شوند و ممکن است نیاز باشد قوانین خاصی به دامنه های قابل تنظیم (مانند init ) اضافه شود.

تغییرات ویژگی برای اندروید 9

دستگاه هایی که به اندروید 9 ارتقا می یابند می توانند از ویژگی های زیر استفاده کنند، اما دستگاه هایی که با اندروید 9 راه اندازی می شوند نباید.

صفات ناقض

Android 9 شامل این ویژگی های مرتبط با دامنه است:

  • data_between_core_and_vendor_violators . مشخصه برای همه دامنه‌هایی که الزام به اشتراک‌گذاری نکردن فایل‌ها از طریق مسیر بین vendor و coredomains را نقض می‌کنند. فرآیندهای پلت فرم و فروشنده نباید از فایل های روی دیسک برای برقراری ارتباط استفاده کنند (ABI ناپایدار). توصیه:
    • کد فروشنده باید از /data/vendor استفاده کند.
    • سیستم نباید /data/vendor استفاده کند.
  • system_executes_vendor_violators . مشخصه برای همه دامنه‌های سیستم (به جز دامنه‌های init و shell domains ) که الزام اجرای نکردن باینری‌های فروشنده را نقض می‌کنند. اجرای باینری های فروشنده دارای API ناپایدار است. پلتفرم نباید باینری های فروشنده را مستقیماً اجرا کند. توصیه:
    • چنین وابستگی های پلتفرمی به باینری های فروشنده باید پشت HIDL HAL ها باشد.

      یا

    • coredomains که نیاز به دسترسی به باینری‌های فروشنده دارند، باید به پارتیشن فروشنده منتقل شوند و بنابراین، coredomain نیستند.

ویژگی های غیر قابل اعتماد

برنامه‌های غیرقابل اعتمادی که کد دلخواه را میزبانی می‌کنند، نباید به سرویس‌های HwBinder دسترسی داشته باشند، به جز برنامه‌هایی که برای دسترسی از چنین برنامه‌هایی به اندازه کافی ایمن در نظر گرفته می‌شوند (به سرویس‌های ایمن زیر مراجعه کنید). دو دلیل اصلی برای این امر عبارتند از:

  1. سرورهای HwBinder احراز هویت مشتری را انجام نمی دهند زیرا HIDL در حال حاضر اطلاعات UID تماس گیرنده را نشان نمی دهد. حتی اگر HIDL چنین داده‌هایی را افشا کند، بسیاری از سرویس‌های HwBinder یا در سطح پایین‌تر از برنامه‌ها (مانند HAL) کار می‌کنند یا نباید برای مجوز به هویت برنامه تکیه کنند. بنابراین، برای ایمن بودن، فرض پیش‌فرض این است که هر سرویس HwBinder با تمام مشتریان خود به‌طور مساوی برای انجام عملیات ارائه‌شده توسط این سرویس دارای مجوز هستند.
  2. سرورهای HAL (زیرمجموعه ای از سرویس های HwBinder) حاوی کدهایی با نرخ بروز مشکلات امنیتی بالاتر از اجزای system/core هستند و به لایه های پایینی پشته دسترسی دارند (تا سخت افزار) بنابراین فرصت های دور زدن مدل امنیتی اندروید را افزایش می دهند. .

خدمات ایمن

خدمات ایمن عبارتند از:

  • same_process_hwservice . این سرویس‌ها (طبق تعریف) در فرآیند مشتری اجرا می‌شوند و بنابراین دسترسی یکسانی به دامنه مشتری دارند که فرآیند در آن اجرا می‌شود.
  • coredomain_hwservice . این خدمات خطرات مرتبط با دلیل شماره 2 را ایجاد نمی کنند.
  • hal_configstore_ISurfaceFlingerConfigs . این سرویس به طور خاص برای استفاده توسط هر دامنه طراحی شده است.
  • hal_graphics_allocator_hwservice . این عملیات همچنین توسط سرویس surfaceflinger Binder ارائه می شود که برنامه ها مجاز به دسترسی به آن هستند.
  • hal_omx_hwservice . این یک نسخه HwBinder از سرویس mediacodec Binder است که برنامه ها مجاز به دسترسی به آن هستند.
  • hal_codec2_hwservice . این نسخه جدیدتر hal_omx_hwservice است.

ویژگی های قابل استفاده

همه hwservices که ایمن در نظر گرفته نمی شوند دارای ویژگی untrusted_app_visible_hwservice هستند. سرورهای HAL مربوطه دارای ویژگی untrusted_app_visible_halserver هستند. دستگاه‌هایی که با Android 9 راه‌اندازی می‌شوند نباید از هیچ یک از ویژگی‌های untrusted استفاده کنند.

توصیه:

  • برنامه‌های غیرقابل اعتماد باید در عوض با سرویس سیستمی که با فروشنده HIDL HAL صحبت می‌کند صحبت کنند. به عنوان مثال، برنامه ها می توانند با binderservicedomain صحبت کنند، سپس mediaserver (که یک binderservicedomain است) به نوبه خود با hal_graphics_allocator صحبت می کند.

    یا

  • برنامه‌هایی که نیاز به دسترسی مستقیم به HAL‌های vendor دارند، باید دامنه سیاست‌گذاری تعریف‌شده توسط فروشنده خود را داشته باشند.

تست های ویژگی فایل

اندروید 9 شامل تست‌های زمان ساخت است که اطمینان می‌دهد همه فایل‌ها در مکان‌های خاص دارای ویژگی‌های مناسب هستند (مانند همه فایل‌های موجود در sysfs دارای ویژگی sysfs_type مورد نیاز هستند).

پلت فرم-سیاست عمومی

خط مشی عمومی پلتفرم هسته اصلی انطباق با مدل معماری Android 8.0 بدون حفظ اتحاد سیاست های پلت فرم از نسخه 1 و 2 است. فروشندگان در معرض زیرمجموعه‌ای از خط‌مشی پلتفرم قرار می‌گیرند که شامل انواع و ویژگی‌های قابل استفاده و قوانین مربوط به آن نوع و ویژگی است که سپس بخشی از خط‌مشی فروشنده می‌شود (یعنی vendor_sepolicy.cil ).

انواع و قوانین به طور خودکار در خط‌مشی تولید شده توسط فروشنده به attribute_v N ترجمه می‌شوند، به طوری که همه انواع ارائه‌شده توسط پلتفرم، ویژگی‌های نسخه‌شده هستند (هر چند ویژگی‌ها نسخه‌بندی نشده‌اند). پلت فرم مسئول نگاشت انواع بتنی که ارائه می کند در ویژگی های مناسب است تا اطمینان حاصل شود که خط مشی فروشنده همچنان به کار خود ادامه می دهد و قوانین ارائه شده برای یک نسخه خاص گنجانده شده است. ترکیبی از خط‌مشی عمومی پلتفرم و خط‌مشی فروشنده، هدف مدل معماری Android 8.0 را برآورده می‌کند که اجازه ساخت پلتفرم و فروشنده مستقل را می‌دهد.

نگاشت به زنجیره های صفت

هنگام استفاده از ویژگی‌ها برای نگاشت به نسخه‌های خط‌مشی، یک نوع به یک ویژگی یا ویژگی‌های متعدد نگاشت می‌شود و اطمینان حاصل می‌کند که اشیاء برچسب‌گذاری شده با نوع از طریق ویژگی‌های مربوط به انواع قبلی‌شان قابل دسترسی هستند.

حفظ هدف برای مخفی کردن اطلاعات نسخه از سیاست نویس به معنای تولید خودکار ویژگی های نسخه شده و اختصاص آنها به انواع مناسب است. در مورد رایج انواع استاتیک، این کار ساده است: type_foo به type_foo_v1 نقشه می‌دهد.

برای تغییر برچسب شی مانند sysfssysfs_A یا mediaserveraudioserver ، ایجاد این نگاشت بی اهمیت است (و در مثال های بالا توضیح داده شده است). نگهدارندگان خط مشی پلت فرم باید نحوه ایجاد نقشه در نقاط انتقال برای اشیا را تعیین کنند، که نیاز به درک رابطه بین اشیا و برچسب های اختصاص داده شده آنها و تعیین زمان وقوع آن دارد. برای سازگاری با عقب، این پیچیدگی باید در سمت پلتفرم مدیریت شود، که تنها پارتیشنی است که ممکن است افزایش یابد.

ارتقاء نسخه

برای سادگی، پلتفرم آندروید یک نسخه sepolicy را هنگامی که یک شاخه نسخه جدید قطع می شود منتشر می کند. همانطور که در بالا توضیح داده شد، شماره نسخه در PLATFORM_SEPOLICY_VERSION موجود است و به شکل MM.nn است، که در آن MM مربوط به مقدار SDK است و nn یک مقدار خصوصی است که در /platform/system/sepolicy. به عنوان مثال، 19.0 برای Kitkat، 21.0 برای Lollipop، 22.0 برای Lollipop-MR1 23.0 برای Marshmallow، 24.0 برای Nougat، 25.0 برای Nougat-MR1، 26.0 برای Oreo، 27.0 برای Oreo-MR1 28.0 برای اندروید هستند. همیشه اعداد کامل به عنوان مثال، اگر یک ضربه MR به یک نسخه نیاز به تغییر ناسازگار در system/sepolicy/public داشته باشد، اما نه یک برآمدگی API، آن نسخه sepolicy می‌تواند این باشد: vN.1 . نسخه موجود در یک شعبه توسعه یک دستگاه غیر قابل استفاده در حمل و نقل 10000.0 است.

ممکن است اندروید در هنگام ارتقاء، قدیمی ترین نسخه را منسوخ کند. برای اطلاعاتی درباره زمان منسوخ شدن یک نسخه، Android ممکن است تعداد دستگاه‌های دارای خط‌مشی‌های فروشنده را جمع‌آوری کند که آن نسخه Android را اجرا می‌کنند و همچنان به‌روزرسانی‌های اصلی پلتفرم را دریافت می‌کنند. اگر عدد کمتر از یک آستانه خاص باشد، آن نسخه منسوخ می شود.

تأثیر عملکرد چندین ویژگی

همانطور که در https://github.com/SELinuxProject/cil/issues/9 توضیح داده شد، تعداد زیادی از ویژگی های اختصاص داده شده به یک نوع در صورت از دست رفتن حافظه پنهان سیاست، منجر به مشکلات عملکرد می شود.

تأیید شد که این مشکل در Android وجود دارد، بنابراین تغییراتی در Android 8.0 برای حذف ویژگی‌های اضافه شده به خط‌مشی توسط کامپایلر خط‌مشی و همچنین حذف ویژگی‌های استفاده نشده اعمال شد . این تغییرات رگرسیون عملکرد را حل کرد.

System_ext سیاست عمومی و عمومی محصول

از Android 11، پارتیشن‌های system_ext و product مجاز هستند انواع عمومی تعیین‌شده خود را به پارتیشن فروشنده صادر کنند. مانند خط‌مشی عمومی پلتفرم، فروشنده از انواع و قوانینی استفاده می‌کند که به‌طور خودکار به ویژگی‌های نسخه‌شده ترجمه می‌شوند، به عنوان مثال از type به type_ N ، که در آن N نسخه پلتفرمی است که پارتیشن فروشنده بر اساس آن ساخته شده است.

هنگامی که پارتیشن‌های system_ext و محصول بر اساس همان پلتفرم نسخه N هستند، سیستم ساخت فایل‌های نگاشت پایه را به system_ext/etc/selinux/mapping/ N .cil و product/etc/selinux/mapping/ N .cil تولید می‌کند که حاوی هویت هستند. نگاشت از type به type_ N . فروشنده می تواند type با ویژگی نسخه شده type_ N دسترسی پیدا کند.

در صورتی که فقط پارتیشن‌های system_ext و محصول، مثلاً N به N+1 (یا جدیدتر) به‌روزرسانی شوند، در حالی که فروشنده در N بماند، ممکن است فروشنده دسترسی به انواع پارتیشن‌های system_ext و محصول را از دست بدهد. برای جلوگیری از شکستگی، پارتیشن‌های system_ext و product باید فایل‌های نقشه‌برداری را از انواع بتن به ویژگی‌های type_ N ارائه دهند. هر شریک مسئولیت نگهداری فایل‌های نگاشت را بر عهده دارد، اگر قرار است از N فروشنده با N+1 (یا بالاتر) system_ext و پارتیشن‌های محصول پشتیبانی کند.

برای انجام این کار، از شرکا انتظار می رود:

  1. فایل های نگاشت پایه ایجاد شده را از N system_ext و پارتیشن های محصول در درخت منبع آنها کپی کنید.
  2. فایل های نقشه برداری را در صورت نیاز اصلاح کنید.
  3. فایل های نگاشت را در N+1 (یا جدیدتر) system_ext و پارتیشن های محصول نصب کنید.

برای مثال، فرض کنید N system_ext یک نوع عمومی به نام foo_type دارد. سپس system_ext/etc/selinux/mapping/ N .cil در پارتیشن N system_ext به شکل زیر خواهد بود:

(typeattributeset foo_type_N (foo_type))
(expandtypeattribute foo_type_N true)
(typeattribute foo_type_N)

اگر bar_type به N+1 system_ext اضافه شود، و اگر bar_type باید به foo_type برای N فروشنده نگاشت شود، N .cil را می توان از

(typeattributeset foo_type_N (foo_type))

به

(typeattributeset foo_type_N (foo_type bar_type))

و سپس در پارتیشن N+1 system_ext نصب می شود. N فروشنده می تواند به دسترسی به foo_type و bar_type N+1 system_ext ادامه دهد.

برچسب زدن زمینه های SELinux

برای حمایت از تمایز بین پلتفرم و سیاست فروشنده، سیستم فایل‌های زمینه SELinux را متفاوت می‌سازد تا آنها را جدا نگه دارد.

زمینه های فایل

اندروید 8.0 تغییرات زیر را برای file_contexts ارائه کرد:

  • برای جلوگیری از سربار کامپایل اضافی روی دستگاه در هنگام بوت کردن، file_contexts به شکل باینری وجود ندارد. درعوض، فایل متنی با بیان منظم مانند {property, service}_contexts (همانطور که قبل از 7.0 بودند) قابل خواندن هستند.
  • file_contexts بین دو فایل تقسیم می شود:
    • plat_file_contexts
      • file_context پلتفرم Android که هیچ برچسب مخصوص دستگاه ندارد، به جز برای برچسب زدن قسمت‌هایی از پارتیشن /vendor که باید دقیقاً برچسب‌گذاری شوند تا از عملکرد صحیح فایل‌های sepolicy اطمینان حاصل شود.
      • باید در پارتیشن system در /system/etc/selinux/plat_file_contexts روی دستگاه قرار داشته باشد و توسط init در ابتدا همراه با فروشنده file_context بارگذاری شود.
    • vendor_file_contexts
      • file_context مخصوص دستگاه که با ترکیب file_contexts موجود در فهرست‌های راهنمای BOARD_SEPOLICY_DIRS در فایل‌های Boardconfig.mk دستگاه ساخته شده است.
      • باید در /vendor/etc/selinux/vendor_file_contexts در پارتیشن vendor نصب شود و در ابتدا توسط init همراه با file_context پلتفرم بارگذاری شود.

زمینه های ملکی

در اندروید 8.0، property_contexts بین دو فایل تقسیم می‌شود:

  • plat_property_contexts
    • property_context پلتفرم Android که برچسب مخصوص دستگاه ندارد.
    • باید در پارتیشن system در /system/etc/selinux/plat_property_contexts قرار داشته باشد و توسط init در ابتدا همراه با vendor property_contexts بارگذاری شود.
  • vendor_property_contexts
    • property_context مخصوص دستگاه با ترکیب property_contexts یافت شده در دایرکتوری های اشاره شده توسط BOARD_SEPOLICY_DIRS در فایل های Boardconfig.mk دستگاه ساخته شده است.
    • باید در پارتیشن vendor در /vendor/etc/selinux/vendor_property_contexts قرار داشته باشد و در ابتدا توسط init به همراه property_context پلت فرم بارگذاری شود.

زمینه های خدماتی

در اندروید 8.0، service_contexts بین فایل‌های زیر تقسیم می‌شود:

  • plat_service_contexts
    • service_context مخصوص پلتفرم Android برای servicemanager . service_context هیچ برچسب مخصوص دستگاه ندارد.
    • باید در پارتیشن system در /system/etc/selinux/plat_service_contexts قرار داشته باشد و توسط servicemanager در ابتدا همراه با فروشنده service_contexts بارگیری شود.
  • vendor_service_contexts
    • service_context مخصوص دستگاه که با ترکیب service_contexts یافت شده در دایرکتوری های اشاره شده توسط BOARD_SEPOLICY_DIRS در فایل های Boardconfig.mk دستگاه ساخته شده است.
    • باید در پارتیشن vendor در /vendor/etc/selinux/vendor_service_contexts قرار داشته باشد و توسط servicemanager در ابتدا همراه با platform service_contexts بارگیری شود.
    • اگرچه servicemanager در زمان راه‌اندازی به دنبال این فایل می‌گردد، اما برای یک دستگاه TREBLE کاملاً سازگار، vendor_service_contexts نباید وجود داشته باشد. این به این دلیل است که تمام تعامل بین vendor و فرآیندهای system باید از طریق hwservicemanager / hwbinder انجام شود.
  • plat_hwservice_contexts
    • پلتفرم Android hwservice_context برای hwservicemanager که هیچ برچسب مخصوص دستگاه ندارد.
    • باید در پارتیشن system در /system/etc/selinux/plat_hwservice_contexts قرار داشته باشد و در ابتدا توسط hwservicemanager همراه با vendor_hwservice_contexts بارگیری شود.
  • vendor_hwservice_contexts
    • hwservice_context مخصوص دستگاه که با ترکیب hwservice_contexts یافت شده در دایرکتوری های اشاره شده توسط BOARD_SEPOLICY_DIRS در فایل های Boardconfig.mk دستگاه ساخته شده است.
    • باید در پارتیشن vendor در /vendor/etc/selinux/vendor_hwservice_contexts قرار داشته باشد و در ابتدا توسط hwservicemanager همراه با plat_service_contexts بارگیری شود.
  • vndservice_contexts
    • service_context مخصوص دستگاه برای vndservicemanager ساخته شده با ترکیب vndservice_contexts موجود در فهرست‌های راهنمای BOARD_SEPOLICY_DIRS در Boardconfig.mk دستگاه.
    • این فایل باید در پارتیشن vendor در /vendor/etc/selinux/vndservice_contexts قرار داشته باشد و در ابتدا توسط vndservicemanager بارگیری شود.

زمینه های Seapp

در اندروید 8.0، seapp_contexts بین دو فایل تقسیم می‌شود:

  • plat_seapp_contexts
    • پلتفرم Android seapp_context که هیچ تغییری خاص دستگاه ندارد.
    • باید در پارتیشن system در /system/etc/selinux/plat_seapp_contexts.
  • vendor_seapp_contexts
    • پسوند خاص دستگاه برای پلتفرم seapp_context با ترکیب seapp_contexts موجود در فهرست‌های راهنمای BOARD_SEPOLICY_DIRS در فایل‌های Boardconfig.mk دستگاه ساخته شده است.
    • باید در پارتیشن vendor در /vendor/etc/selinux/vendor_seapp_contexts ساکن باشد.

مجوزهای MAC

در اندروید 8.0، mac_permissions.xml بین دو فایل تقسیم می‌شود:

  • پلتفرم mac_permissions.xml
    • پلتفرم Android mac_permissions.xml که هیچ تغییری خاص دستگاه ندارد.
    • باید در پارتیشن system در /system/etc/selinux/.
  • mac_permissions.xml غیرپلتفرمی
    • پسوند مخصوص دستگاه برای پلتفرم mac_permissions.xml ساخته شده از mac_permissions.xml که در فهرست‌های راهنمای BOARD_SEPOLICY_DIRS در فایل‌های Boardconfig.mk دستگاه یافت می‌شود.
    • باید در پارتیشن vendor در /vendor/etc/selinux/.