Triển khai SELinux

SELinux được thiết lập ở chế độ từ chối mặc định, có nghĩa là mọi quyền truy cập duy nhất mà nó có hook trong kernel phải được chính sách cho phép rõ ràng. Điều này có nghĩa là tệp chính sách bao gồm một lượng lớn thông tin liên quan đến quy tắc, loại, lớp, quyền, v.v. Việc xem xét đầy đủ về SELinux nằm ngoài phạm vi của tài liệu này, nhưng sự hiểu biết về cách viết các quy tắc chính sách hiện là điều cần thiết khi đưa ra các thiết bị Android mới. Hiện đã có rất nhiều thông tin liên quan đến SELinux. Xem Tài liệu hỗ trợ để biết các tài nguyên được đề xuất.

Tập tin chính

Để kích hoạt SELinux, hãy tích hợp nhân Android mới nhất rồi kết hợp các tệp được tìm thấy trong thư mục hệ thống/sepolicy . Khi được biên dịch, các tệp đó bao gồm chính sách bảo mật hạt nhân SELinux và bao gồm hệ điều hành Android ngược dòng.

Nói chung, bạn không nên sửa đổi trực tiếp các tệp system/sepolicy . Thay vào đó, hãy thêm hoặc chỉnh sửa các tệp chính sách dành riêng cho thiết bị của bạn trong thư mục /device/ manufacturer / device-name /sepolicy . Trong Android 8.0 trở lên, những thay đổi bạn thực hiện đối với các tệp này sẽ chỉ ảnh hưởng đến chính sách trong thư mục nhà cung cấp của bạn. Để biết thêm chi tiết về việc tách biệt chính sách công khai trong Android 8.0 trở lên, hãy xem Tùy chỉnh chính sách riêng tư trong Android 8.0+ . Bất kể phiên bản Android là gì, bạn vẫn đang sửa đổi các tệp này:

Tệp chính sách

Các tệp kết thúc bằng *.te là các tệp nguồn chính sách SELinux, xác định miền và nhãn của chúng. Bạn có thể cần tạo các tệp chính sách mới trong /device/ manufacturer / device-name /sepolicy , nhưng bạn nên cố gắng cập nhật các tệp hiện có nếu có thể.

Tệp ngữ cảnh

Tệp ngữ cảnh là nơi bạn chỉ định nhãn cho đối tượng của mình.

  • file_contexts gán nhãn cho các tệp và được sử dụng bởi nhiều thành phần không gian người dùng khác nhau. Khi bạn tạo chính sách mới, hãy tạo hoặc cập nhật tệp này để gán nhãn mới cho tệp. Để áp dụng file_contexts mới, hãy xây dựng lại hình ảnh hệ thống tệp hoặc chạy restorecon trên tệp sẽ được gắn nhãn lại. Khi nâng cấp, các thay đổi đối với file_contexts sẽ tự động được áp dụng cho phân vùng hệ thống và dữ liệu người dùng như một phần của quá trình nâng cấp. Các thay đổi cũng có thể được áp dụng tự động khi nâng cấp lên các phân vùng khác bằng cách thêm các lệnh gọi restorecon_recursive vào init. board .rc sau khi phân vùng đã được mount đọc-ghi.
  • genfs_contexts gán nhãn cho các hệ thống tệp, chẳng hạn như proc hoặc vfat không hỗ trợ các thuộc tính mở rộng. Cấu hình này được tải như một phần của chính sách kernel nhưng các thay đổi có thể không có hiệu lực đối với các nút trong lõi, yêu cầu khởi động lại hoặc ngắt kết nối và gắn lại hệ thống tệp để áp dụng đầy đủ thay đổi. Các nhãn cụ thể cũng có thể được gán cho các mount cụ thể, chẳng hạn như vfat bằng cách sử dụng tùy chọn context=mount .
  • property_contexts gán nhãn cho thuộc tính hệ thống Android để kiểm soát những quy trình nào có thể đặt nhãn. Cấu hình này được đọc bởi tiến trình init trong quá trình khởi động.
  • service_contexts gán nhãn cho các dịch vụ liên kết của Android để kiểm soát những quy trình nào có thể thêm (đăng ký) và tìm (tra cứu) tham chiếu liên kết cho dịch vụ. Cấu hình này được đọc bởi tiến trình servicemanager trong quá trình khởi động.
  • seapp_contexts gán nhãn cho các tiến trình ứng dụng và thư mục /data/data . Cấu hình này được đọc bởi quy trình zygote trong mỗi lần khởi chạy ứng dụng và bởi installd trong khi khởi động.
  • mac_permissions.xml gán thẻ seinfo cho các ứng dụng dựa trên chữ ký và tên gói tùy chọn của chúng. Sau đó, thẻ seinfo có thể được sử dụng làm khóa trong tệp seapp_contexts để gán nhãn cụ thể cho tất cả ứng dụng có thẻ seinfo đó. Cấu hình này được đọc bởi system_server trong quá trình khởi động.
  • keystore2_key_contexts gán nhãn cho không gian tên Keystore 2.0. Các không gian tên này được thực thi bởi daemon keystore2. Keystore luôn cung cấp các không gian tên dựa trên UID/AID. Keystore 2.0 còn thực thi thêm các không gian tên được xác định theo chính sách riêng biệt. Bạn có thể tìm thấy mô tả chi tiết về định dạng và quy ước của tệp này tại đây .

Tệp tạo BoardConfig.mk

Sau khi chỉnh sửa hoặc thêm các tệp chính sách và ngữ cảnh, hãy cập nhật tệp makefile /device/ manufacturer / device-name /BoardConfig.mk của bạn để tham chiếu thư mục con sepolicy và mỗi tệp chính sách mới. Để biết thêm thông tin về các biến BOARD_SEPOLICY , hãy xem tệp system/sepolicy/README .

BOARD_SEPOLICY_DIRS += \
        <root>/device/manufacturer/device-name/sepolicy

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

Sau khi xây dựng lại, thiết bị của bạn được kích hoạt SELinux. Giờ đây, bạn có thể tùy chỉnh các chính sách SELinux của mình để phù hợp với các bổ sung của riêng bạn cho hệ điều hành Android như được mô tả trong Tùy chỉnh hoặc xác minh thiết lập hiện tại của bạn như được đề cập trong Xác thực .

Khi có các tệp chính sách mới và các bản cập nhật BoardConfig.mk, các cài đặt chính sách mới sẽ tự động được tích hợp vào tệp chính sách kernel cuối cùng. Để biết thêm thông tin về cách xây dựng chính sách riêng biệt trên thiết bị, hãy xem Xây dựng chính sách riêng biệt .

Thực hiện

Để bắt đầu với SELinux:

  1. Kích hoạt SELinux trong kernel: CONFIG_SECURITY_SELINUX=y
  2. Thay đổi tham số kernel_cmdline hoặc bootconfig sao cho:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    hoặc
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    Điều này chỉ dành cho việc phát triển chính sách ban đầu cho thiết bị. Sau khi bạn có chính sách khởi động ban đầu, hãy xóa tham số này để thiết bị của bạn đang thực thi nếu không nó sẽ bị lỗi CTS.
  3. Khởi động hệ thống ở chế độ cho phép và xem những từ chối nào gặp phải khi khởi động:
    Trên Ubuntu 14.04 hoặc mới hơn:
    adb shell su -c dmesg | grep denied | audit2allow -p out/target/product/BOARD/root/sepolicy
    
    Trên Ubuntu 12.04:
    adb pull /sys/fs/selinux/policy
    adb logcat -b all | audit2allow -p policy
    
  4. Đánh giá đầu ra để tìm các cảnh báo giống với init: Warning! Service name needs a SELinux domain defined; please fix! Xem Xác thực để biết hướng dẫn và công cụ.
  5. Xác định thiết bị và các tệp mới khác cần gắn nhãn.
  6. Sử dụng nhãn hiện có hoặc nhãn mới cho đối tượng của bạn. Xem các tệp *_contexts để biết mọi thứ được gắn nhãn trước đó như thế nào và sử dụng kiến ​​thức về ý nghĩa của nhãn để gán nhãn mới. Lý tưởng nhất là đây sẽ là nhãn hiện có phù hợp với chính sách, nhưng đôi khi cần có nhãn mới và cần có các quy tắc để truy cập vào nhãn đó. Thêm nhãn của bạn vào các tệp ngữ cảnh thích hợp.
  7. Xác định các miền/quy trình cần có miền bảo mật riêng. Bạn có thể sẽ cần phải viết một chính sách hoàn toàn mới cho mỗi chính sách. Ví dụ: tất cả các dịch vụ được sinh ra từ init đều phải có dịch vụ riêng. Các lệnh sau giúp tiết lộ những lệnh vẫn đang chạy (nhưng TẤT CẢ các dịch vụ đều cần cách xử lý như vậy):
    adb shell su -c ps -Z | grep init
    
    adb shell su -c dmesg | grep 'avc: '
    
  8. Xem lại init. device .rc để xác định bất kỳ miền nào không có loại miền. Hãy sớm cung cấp cho họ một miền trong quá trình phát triển của bạn để tránh thêm các quy tắc vào init hoặc gây nhầm lẫn giữa các quyền truy cập init với các quy tắc có trong chính sách của riêng họ.
  9. Thiết lập BOARD_CONFIG.mk để sử dụng các biến BOARD_SEPOLICY_* . Xem README trong system/sepolicy để biết chi tiết về cách thiết lập tính năng này.
  10. Kiểm tra init. device .rc và fstab. device và đảm bảo mỗi lần sử dụng mount đều tương ứng với hệ thống tệp được gắn nhãn chính xác hoặc tùy chọn context= mount được chỉ định.
  11. Đi qua từng từ chối và tạo chính sách SELinux để xử lý chính xác từng từ chối. Xem các ví dụ trong Tùy chỉnh .

Bạn nên bắt đầu với các chính sách trong AOSP, sau đó xây dựng dựa trên các chính sách đó để thực hiện các tùy chỉnh của riêng mình. Để biết thêm thông tin về chiến lược chính sách và xem xét kỹ hơn một số bước này, hãy xem Viết chính sách SELinux .

Trường hợp sử dụng

Dưới đây là các ví dụ cụ thể về việc khai thác cần xem xét khi tạo phần mềm của riêng bạn và các chính sách SELinux liên quan:

Liên kết tượng trưng - Vì liên kết tượng trưng xuất hiện dưới dạng tệp nên chúng thường được đọc dưới dạng tệp, điều này có thể dẫn đến việc khai thác. Ví dụ: một số thành phần đặc quyền, chẳng hạn như init , thay đổi quyền của một số tệp nhất định, đôi khi bị mở quá mức.

Sau đó, kẻ tấn công có thể thay thế các tệp đó bằng các liên kết tượng trưng đến mã mà chúng kiểm soát, cho phép kẻ tấn công ghi đè lên các tệp tùy ý. Nhưng nếu bạn biết ứng dụng của mình sẽ không bao giờ đi qua một liên kết tượng trưng, ​​bạn có thể cấm nó làm như vậy với SELinux.

Tệp hệ thống - Hãy xem xét loại tệp hệ thống chỉ được sửa đổi bởi máy chủ hệ thống. Tuy nhiên, vì netd , initvold chạy bằng root nên chúng có thể truy cập các tệp hệ thống đó. Vì vậy, nếu netd bị xâm phạm, nó có thể xâm phạm các tệp đó và có thể cả chính máy chủ hệ thống.

Với SELinux, bạn có thể xác định những tệp đó là tệp dữ liệu máy chủ hệ thống. Do đó, miền duy nhất có quyền truy cập đọc/ghi vào chúng là máy chủ hệ thống. Ngay cả khi netd bị xâm phạm, nó không thể chuyển miền sang miền máy chủ hệ thống và truy cập các tệp hệ thống đó mặc dù nó chạy bằng root.

Dữ liệu ứng dụng - Một ví dụ khác là lớp hàm phải chạy dưới quyền root nhưng không được truy cập dữ liệu ứng dụng. Điều này cực kỳ hữu ích vì có thể đưa ra các xác nhận trên phạm vi rộng, chẳng hạn như một số miền nhất định không liên quan đến dữ liệu ứng dụng bị cấm truy cập internet.

setattr - Đối với các lệnh như chmodchown , bạn có thể xác định tập hợp các tệp mà miền liên kết có thể tiến hành setattr . Bất cứ điều gì bên ngoài điều đó có thể bị cấm đối với những thay đổi này, ngay cả bằng root. Vì vậy, một ứng dụng có thể chạy chmodchown lại những ứng dụng được gắn nhãn app_data_files chứ không phải shell_data_files hoặc system_data_files .