Xây dựng chính sách SELinux

Bài viết này trình bày cách xây dựng chính sách SELinux. Chính sách SELinux được xây dựng từ sự kết hợp giữa chính sách AOSP cốt lõi (nền tảng) và chính sách dành riêng cho thiết bị (nhà cung cấp). Luồng xây dựng chính sách SELinux dành cho Android 4.4 đến Android 7.0 đã hợp nhất tất cả các phân đoạn riêng biệt sau đó tạo các tệp nguyên khối trong thư mục gốc. Điều này có nghĩa là các nhà cung cấp SoC và nhà sản xuất ODM đã sửa đổi boot.img (đối với thiết bị không phải A/B) hoặc system.img (đối với thiết bị A/B) mỗi khi chính sách được sửa đổi.

Trong Android 8.0 trở lên, chính sách nền tảng và nhà cung cấp được xây dựng riêng biệt. SOC và OEM có thể cập nhật các phần chính sách của họ, xây dựng hình ảnh của họ (chẳng hạn như vendor.imgboot.img ), sau đó cập nhật những hình ảnh đó độc lập với các bản cập nhật nền tảng.

Tuy nhiên, vì các tệp chính sách SELinux được mô-đun hóa được lưu trữ trên các phân vùng /vendor , quá trình init phải gắn kết các phân vùng hệ thống và nhà cung cấp trước đó để nó có thể đọc các tệp SELinux từ các phân vùng đó và hợp nhất chúng với các tệp SELinux lõi trong thư mục hệ thống (trước khi tải chúng vào hạt nhân).

Tệp nguồn

Logic để xây dựng SELinux nằm trong các tệp này:

  • external/selinux : Dự án SELinux bên ngoài, được sử dụng để xây dựng các tiện ích dòng lệnh HOST nhằm biên dịch chính sách và nhãn SELinux.
    • external/selinux/libselinux : Android chỉ sử dụng một tập hợp con của dự án libselinux bên ngoài cùng với một số tùy chỉnh dành riêng cho Android. Để biết chi tiết, hãy xem external/selinux/README.android .
    • external/selinux/libsepol :
      • chkcon : Xác định xem bối cảnh bảo mật có hợp lệ đối với chính sách nhị phân nhất định hay không (máy chủ thực thi).
      • libsepol : Thư viện SELinux để thao tác các chính sách bảo mật nhị phân (thư viện tĩnh/chia sẻ máy chủ, thư viện tĩnh đích).
    • external/selinux/checkpolicy : Trình biên dịch chính sách SELinux (các tệp thực thi trên máy chủ: checkpolicy , checkmoduledispol ). Phụ thuộc vào libsepol .
  • system/sepolicy : Cấu hình chính sách Android SELinux cốt lõi, bao gồm các tệp ngữ cảnh và chính sách. Logic xây dựng chính sách riêng biệt chính cũng có ở đây ( system/sepolicy/Android.mk ).

Để biết thêm chi tiết về các tệp trong system/sepolicy Triển khai SELinux .

Android 7.0 trở về trước

Phần này trình bày cách xây dựng chính sách SELinux trong Android 7.x trở về trước.

Xây dựng chính sách SELinux

Chính sách SELinux được tạo bằng cách kết hợp chính sách AOSP cốt lõi với các tùy chỉnh dành riêng cho thiết bị. Chính sách kết hợp sau đó được chuyển tới trình biên dịch chính sách và các trình kiểm tra khác nhau. Việc tùy chỉnh dành riêng cho thiết bị được thực hiện thông qua biến BOARD_SEPOLICY_DIRS được xác định trong tệp Boardconfig.mk dành riêng cho thiết bị. Biến xây dựng toàn cầu này chứa danh sách các thư mục chỉ định thứ tự tìm kiếm các tệp chính sách bổ sung.

Ví dụ: mỗi nhà cung cấp SoC và một ODM có thể thêm một thư mục, một thư mục dành cho cài đặt dành riêng cho SoC và thư mục khác dành cho cài đặt dành riêng cho thiết bị, để tạo cấu hình SELinux cuối cùng cho một thiết bị nhất định:

  • BOARD_SEPOLICY_DIRS += device/ SOC /common/sepolicy
  • BOARD_SEPOLICY_DIRS += device/ SoC / DEVICE /sepolicy

Nội dung của các tệp file_contexts trong system/sepolicyBOARD_SEPOLICY_DIRS được nối để tạo file_contexts.bin trên thiết bị:

Hình ảnh này hiển thị logic xây dựng SELinux cho Android 7.x.
Hình 1 . Logic xây dựng SELinux

Tệp sepolicy bao gồm nhiều tệp nguồn:

  • Văn bản thuần túy policy.conf được tạo bằng cách ghép security_classes , initial_sids , *.te , genfs_contextsport_contexts theo thứ tự đó.
  • Đối với mỗi tệp (chẳng hạn như security_classes ), nội dung của nó là sự ghép nối của các tệp có cùng tên trong system/sepolicy/BOARDS_SEPOLICY_DIRS .
  • policy.conf được gửi đến trình biên dịch SELinux để kiểm tra cú pháp và được biên dịch thành định dạng nhị phân dưới dạng sepolicy trên thiết bị.
    Hình ảnh này hiển thị các tệp tạo tệp chính sách SELinux cho Android 7.x.
    Hình 2 . Tệp chính sách SELinux

Các tập tin SELinux

Sau khi biên dịch, các thiết bị Android chạy 7.x trở về trước thường chứa các tệp liên quan đến SELinux sau:

  • selinux_version
  • sepolicy: đầu ra nhị phân sau khi kết hợp các tệp chính sách (chẳng hạn như security_classes , initial_sids*.te )
  • file_contexts
  • property_contexts
  • seapp_contexts
  • service_contexts
  • system/etc/mac_permissions.xml

Để biết thêm chi tiết, hãy xem Triển khai SELinux .

Khởi tạo SELinux

Khi hệ thống khởi động, SELinux ở chế độ cho phép (và không ở chế độ thực thi). Quá trình init thực hiện các tác vụ sau:

  • Tải các tệp sepolicy từ ramdisk vào kernel thông qua /sys/fs/selinux/load .
  • Chuyển SELinux sang chế độ thực thi.
  • Chạy re-exec() để áp dụng quy tắc miền SELinux cho chính nó.

Để rút ngắn thời gian khởi động, hãy thực hiện re-exec() trên quy trình init càng sớm càng tốt.

Android 8.0 trở lên

Trong Android 8.0, chính sách SELinux được chia thành các thành phần nền tảng và nhà cung cấp để cho phép cập nhật chính sách nền tảng/nhà cung cấp độc lập trong khi vẫn duy trì khả năng tương thích.

Chính sách riêng biệt của nền tảng được chia thành các phần riêng tư của nền tảng và các phần công khai của nền tảng để xuất các loại và thuộc tính cụ thể cho người viết chính sách của nhà cung cấp. Các loại/thuộc tính công khai của nền tảng được đảm bảo duy trì dưới dạng API ổn định cho một phiên bản nền tảng nhất định. Khả năng tương thích với các loại/thuộc tính công khai của nền tảng trước đó có thể được đảm bảo cho một số phiên bản sử dụng tệp ánh xạ nền tảng.

Chính sách công khai của nền tảng

Chính sách công khai của nền tảng bao gồm mọi thứ được xác định trong system/sepolicy/public . Nền tảng có thể giả định các loại và thuộc tính được xác định theo chính sách công là các API ổn định cho một phiên bản nền tảng nhất định. Điều này tạo thành một phần của chính sách riêng biệt được xuất bởi nền tảng mà trên đó các nhà phát triển chính sách của nhà cung cấp (tức là thiết bị) có thể viết chính sách bổ sung dành riêng cho thiết bị.

Các loại được tạo phiên bản theo phiên bản của chính sách mà các tệp của nhà cung cấp được viết dựa trên đó, được xác định bởi biến xây dựng PLATFORM_SEPOLICY_VERSION . Sau đó, chính sách công đã được phiên bản sẽ được đưa vào chính sách của nhà cung cấp và (ở dạng ban đầu) trong chính sách nền tảng. Do đó, chính sách cuối cùng bao gồm chính sách nền tảng riêng, chính sách riêng biệt công khai của nền tảng hiện tại, chính sách dành riêng cho thiết bị và chính sách công khai được phiên bản tương ứng với phiên bản nền tảng mà chính sách thiết bị được viết dựa trên đó.

Chính sách riêng tư của nền tảng

Chính sách riêng tư của nền tảng bao gồm mọi thứ được xác định trong /system/sepolicy/private . Phần này của chính sách hình thành các loại, quyền và thuộc tính chỉ dành cho nền tảng cần thiết cho chức năng của nền tảng. Chúng không được xuất cho người viết chính sách vendor/device . Người viết chính sách không thuộc nền tảng không được viết phần mở rộng chính sách của họ dựa trên các loại/thuộc tính/quy tắc được xác định trong chính sách riêng tư của nền tảng. Hơn nữa, các quy tắc này được phép sửa đổi hoặc có thể biến mất như một phần của bản cập nhật chỉ dành cho khung.

Ánh xạ riêng tư của nền tảng

Ánh xạ riêng tư nền tảng bao gồm các tuyên bố chính sách ánh xạ các thuộc tính được hiển thị trong chính sách công khai nền tảng của các phiên bản nền tảng trước đó với các loại cụ thể được sử dụng trong chính sách công khai nền tảng hiện tại. Điều này đảm bảo chính sách của nhà cung cấp được viết dựa trên các thuộc tính công khai của nền tảng từ (các) phiên bản chính sách công khai của nền tảng trước đó tiếp tục hoạt động. Việc lập phiên bản dựa trên biến xây dựng PLATFORM_SEPOLICY_VERSION được đặt trong AOSP cho một phiên bản nền tảng nhất định. Một tệp ánh xạ riêng biệt tồn tại cho từng phiên bản nền tảng trước đó mà nền tảng này dự kiến ​​sẽ chấp nhận chính sách của nhà cung cấp. Để biết thêm chi tiết, hãy xem Khả năng tương thích .

Android 11 trở lên

system_ext và chính sách sản phẩm

Trong Android 11, chính sách system_ext và chính sách sản phẩm được thêm vào. Giống như chính sách riêng biệt của nền tảng, chính sách system_ext và chính sách sản phẩm được chia thành chính sách công và chính sách riêng.

Chính sách công được xuất khẩu cho nhà cung cấp. Các loại và thuộc tính trở thành API ổn định và chính sách của nhà cung cấp có thể tham chiếu đến các loại và thuộc tính trong chính sách công. Các loại được tạo phiên bản theo PLATFORM_SEPOLICY_VERSION và chính sách được tạo phiên bản được đưa vào chính sách của nhà cung cấp. Chính sách ban đầu được bao gồm trong mỗi phân vùng system_ext và sản phẩm.

Chính sách riêng tư chứa các loại, quyền và thuộc tính chỉ dành cho hệ thống và chỉ dành cho sản phẩm cho chức năng của phân vùng sản phẩm và system_ext. Chính sách riêng tư là vô hình đối với nhà cung cấp, ngụ ý rằng các quy tắc này là nội bộ và được phép sửa đổi.

system_ext và ánh xạ sản phẩm

system_ext và sản phẩm được phép xuất các loại công khai được chỉ định của chúng cho nhà cung cấp. Tuy nhiên, trách nhiệm duy trì khả năng tương thích là của mỗi đối tác. Để tương thích, các đối tác có thể cung cấp tệp ánh xạ của riêng họ để ánh xạ các thuộc tính được phiên bản của các phiên bản trước với các loại cụ thể được sử dụng trong chính sách công khai hiện tại.

  • Để cài đặt tệp ánh xạ cho system_ext, hãy đặt tệp cil chứa thông tin ánh xạ mong muốn vào {SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , sau đó thêm system_ext_{ver}.cil vào PRODUCT_PACKAGES .
  • Để cài đặt tệp ánh xạ cho sản phẩm, hãy đặt tệp cil chứa thông tin ánh xạ mong muốn vào {PRODUCT_PRIVATE_SEPOLICY_DIRS}/compat/{ver}/{ver}.cil , sau đó thêm product_{ver}.cil vào PRODUCT_PACKAGES .
  • Tham khảo ví dụ thêm tệp ánh xạ phân vùng sản phẩm của thiết bị redbull.

    Xây dựng chính sách SELinux

    Chính sách SELinux trong Android 8.0 được thực hiện bằng cách kết hợp các phần từ /system/vendor . Logic để thiết lập điều này một cách thích hợp nằm trong /platform/system/sepolicy/Android.mk .

    Chính sách tồn tại ở các vị trí sau:

    Vị trí Chứa
    system/sepolicy/public API riêng biệt của nền tảng
    system/sepolicy/private Chi tiết triển khai nền tảng (nhà cung cấp có thể bỏ qua)
    system/sepolicy/vendor Các tệp chính sách và ngữ cảnh mà nhà cung cấp có thể sử dụng (nhà cung cấp có thể bỏ qua nếu muốn)
    BOARD_SEPOLICY_DIRS Chính sách riêng biệt của nhà cung cấp
    BOARD_ODM_SEPOLICY_DIRS (Android 9 trở lên) Chính sách riêng biệt của Odm
    SYSTEM_EXT_PUBLIC_SEPOLICY_DIRS (Android 11 trở lên) API riêng biệt của System_ext
    SYSTEM_EXT_PRIVATE_SEPOLICY_DIRS (Android 11 trở lên) Chi tiết triển khai System_ext (nhà cung cấp có thể bỏ qua)
    PRODUCT_PUBLIC_SEPOLICY_DIRS (Android 11 trở lên) API riêng biệt của sản phẩm
    PRODUCT_PRIVATE_SEPOLICY_DIRS (Android 11 trở lên) Chi tiết triển khai sản phẩm (nhà cung cấp có thể bỏ qua)

    Hệ thống xây dựng thực hiện chính sách này và tạo ra các thành phần chính sách hệ thống, system_ext, sản phẩm, nhà cung cấp và odm trên phân vùng tương ứng. Các bước bao gồm:

    1. Chuyển đổi chính sách sang định dạng Ngôn ngữ trung gian chung (CIL) SELinux, cụ thể:
      1. chính sách nền tảng công cộng (hệ thống + system_ext + sản ​​phẩm)
      2. chính sách công + tư kết hợp
      3. chính sách công cộng + nhà cung cấp và BOARD_SEPOLICY_DIRS
    2. Phiên bản chính sách do công chúng cung cấp như một phần của chính sách nhà cung cấp. Được thực hiện bằng cách sử dụng chính sách CIL công khai được tạo để thông báo cho chính sách công cộng + nhà cung cấp + BOARD_SEPOLICY_DIRS kết hợp về những phần nào phải được chuyển thành thuộc tính sẽ được liên kết với chính sách nền tảng.
    3. Tạo tệp ánh xạ liên kết nền tảng và các bộ phận của nhà cung cấp. Ban đầu, điều này chỉ liên kết các loại từ chính sách công với các thuộc tính tương ứng trong chính sách của nhà cung cấp; sau này nó cũng sẽ cung cấp cơ sở cho tệp được duy trì trong các phiên bản nền tảng trong tương lai, cho phép tương thích với chính sách của nhà cung cấp nhắm mục tiêu đến phiên bản nền tảng này.
    4. Kết hợp các tệp chính sách (mô tả cả giải pháp trên thiết bị và giải pháp được biên dịch trước).
      1. Kết hợp ánh xạ, nền tảng và chính sách nhà cung cấp.
      2. Biên dịch tập tin chính sách nhị phân đầu ra.

    Chính sách SELinux được biên dịch sẵn

    Trước khi init bật SELinux, init tập hợp tất cả các tệp CIL từ các phân vùng ( system , system_ext , product , vendorodm ) và biên dịch chúng thành chính sách nhị phân, định dạng có thể được tải vào kernel. Vì quá trình biên dịch mất thời gian (thường là 1-2 giây), nên các tệp CIL được biên dịch trước tại thời điểm xây dựng và được đặt tại /vendor/etc/selinux/precompiled_sepolicy hoặc /odm/etc/selinux/precompiled_sepolicy , cùng với hàm băm sha256 của các tập tin CIL đầu vào. Khi chạy, init kiểm tra xem có bất kỳ tệp chính sách nào đã được cập nhật hay không bằng cách so sánh các giá trị băm. Nếu không có gì thay đổi, init sẽ tải chính sách được biên dịch trước. Nếu không, init sẽ biên dịch nhanh chóng và sử dụng nó thay vì biên dịch trước.

    Cụ thể hơn, chính sách biên dịch trước được sử dụng nếu đáp ứng tất cả các điều kiện sau. Ở đây, {partition} đại diện cho phân vùng nơi tồn tại chính sách được biên dịch trước: vendor hoặc odm .

    • Cả /system/etc/selinux/plat_sepolicy_and_mapping.sha256/{partition}/etc/selinux/precompiled_sepolicy.plat_sepolicy_and_mapping.sha256 đều tồn tại và giống hệt nhau.
    • Cả /system_ext/etc/selinux/system_ext_sepolicy_and_mapping.sha256/{partition}/etc/selinux/precompiled_sepolicy.system_ext_sepolicy_and_mapping.sha256 đều không tồn tại. Hoặc cả hai đều tồn tại và giống hệt nhau.
    • Cả /product/etc/selinux/product_sepolicy_and_mapping.sha256/{partition}/etc/selinux/precompiled_sepolicy.product_sepolicy_and_mapping.sha256 đều không tồn tại. Hoặc cả hai đều tồn tại và giống hệt nhau.

    Nếu bất kỳ cái nào trong số chúng khác nhau, init sẽ quay trở lại đường dẫn biên dịch trên thiết bị. Xem system/core/init/selinux.cpp để biết thêm chi tiết.