Triển khai SELinux

SELinux được thiết lập để từ chối theo mặc định, nghĩa là mọi quyền truy cập mà SELinux có một móc trong nhân đều 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 các quy tắc, loại, lớp, quyền và nhiều thông tin khác. Cân nhắc đầy đủ về SELinux nằm ngoài phạm vi của tài liệu này, nhưng không hiểu được cách viết quy tắc chính sách hiện là cần thiết khi hiển thị thiết bị Android mới. Có một đã có rất nhiều thông tin về SELinux. Hãy xem Tài liệu hỗ trợ để biết các tài nguyên được đề xuất.

Tệp khoá

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

Nhìn chung, bạn không nên sửa đổi các tệp system/sepolicy trực tiếp. 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 /device/manufacturer/device-name/sepolicy thư mục. Trên 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 chỉ ảnh hưởng đến chính sách trong thư mục nhà cung cấp. Để biết thêm chi tiết về việc phân tách sepolicy công khai trong Android 8.0 trở lên, hãy xem Tuỳ chỉnh SEPolicy trong Android 8.0 trở lên. Bất kể phiên bản Android, bạn vẫn đang sửa đổi các tệp sau:

Tệp chính sách

Các tệp kết thúc bằng *.te là tệp nguồn chính sách SELinux, giúp xác định các miền và nhãn của các miền đó. 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 các đối tượng.

  • file_contexts gán nhãn cho các tệp và được nhiều người khác nhau sử dụng không gian người dùng. 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 để chỉ định nhãn mới cho các tệp. Cách áp dụng file_contexts mới: tạo 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 các phân vùng dữ liệu người dùng và hệ thống như một phần của nâng cấp. Bạn cũng có thể tự động áp dụng các thay đổi 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 tệp init.board.rc sau khi phân vùng đã được gắn ở chế độ đọc-ghi.
  • genfs_contexts chỉ định nhãn cho các hệ thống tệp, chẳng hạn như proc hoặc vfat không hỗ trợ tính năng mở rộng . Cấu hình này được tải như một phần của chính sách nhân hệ điều hành 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, đòi hỏi phải khởi động lại hoặc ngắt kết nối và kết nối lại hệ thống tệp để áp dụng đầy đủ thay đổi. Bạn cũng có thể gán các nhãn cụ thể cho các giá đỡ cụ thể, chẳng hạn như vfat bằng cách sử dụng tuỳ chọn context=mount.
  • property_contexts gán nhãn cho các thuộc tính hệ thống Android để kiểm soát những quy trình có thể đặt nhãn. Cấu hình này được quá trình init đọc trong quá trình khởi động.
  • service_contexts chỉ định nhãn cho các dịch vụ liên kết của Android kiểm soát những quy trình có thể thêm (đăng ký) và tìm (tra cứu) một liên kết cho dịch vụ. Cấu hình này được đọc bằng Quá trình servicemanager trong khi khởi động.
  • seapp_contexts gán nhãn cho các quy trình ứng dụng và thư mục /data/data. Cấu hình này được đọc bằng Quy trình zygote trong mỗi lần khởi chạy ứng dụng và muộn nhất vào ngày 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 (không bắt buộc). Sau đó, bạn có thể sử dụng thẻ seinfo làm khoá trong tệp seapp_contexts để chỉ định một nhãn cụ thể cho tất cả ứng dụng có thẻ seinfo đó. Người đọc cấu hình này system_server trong khi khởi động.
  • keystore2_key_contexts chỉ định nhãn cho các không gian tên Kho khoá 2.0. Các không gian tên này được thực thi bởi trình nền keystore2. Kho khoá luôn cung cấp không gian tên dựa trên UID/AID. Kho khoá 2.0 cũng thực thi các không gian tên được xác định trong chính sách bảo mật. Bạn có thể xem nội dung mô tả chi tiết về định dạng và quy ước của tệp này tại đây.

Tệp makefile BoardConfig.mk

Sau khi chỉnh sửa hoặc thêm tệp chính sách và ngữ cảnh, hãy cập nhật tệp bản dựng /device/manufacturer/device-name/BoardConfig.mk để tham chiếu thư mục con sepolicy và từng 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 system/sepolicy/README.

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

BOARD_SEPOLICY_UNION += \
        genfs_contexts \
        file_contexts \
        sepolicy.te

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

Khi có các tệp chính sách mới và nội dung cập nhật BoardConfig.mk, cài đặt chính sách được tự động tích hợp vào tệp chính sách nhân hệ điều hành cuối cùng. Để biết thêm thông tin về cách tạo sepolicy trên thiết bị, hãy xem phần Tạo sepolicy.

Triển khai

Cách bắt đầu sử dụng SELinux:

  1. Bật SELinux trong nhân: CONFIG_SECURITY_SELINUX=y
  2. Thay đổi tham số kernel_cmdline hoặc bootconfig để:
    BOARD_KERNEL_CMDLINE := androidboot.selinux=permissive
    hoặc
    BOARD_BOOTCONFIG := androidboot.selinux=permissive
    Đây chỉ là để phát triển chính sách ban đầu cho thiết bị. Sau khi có chính sách tự khởi động ban đầu, hãy xóa tham số này để thiết bị đang thực thi hoặc không thành công CTS.
  3. Khởi động hệ thống ở chế độ cho phép và xem những trường hợp từ chối gặp phải khi khởi động:
    Trên Ubuntu 14.04 trở lê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á kết quả để tìm các cảnh báo tương tự như init: Warning! Service name needs a SELinux domain defined; please fix! Xem Xác thực để xem 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. Hãy xem *_contexts tệp để xem cách các mục đã được gắn nhãn trước đó và sử dụng kiến thức về ý nghĩa của nhãn để gán một nhãn mới. Tốt nhất là bạn nên đây là một nhãn hiện có phù hợp với chính sách, nhưng đôi khi bạn cần một nhãn mới và các quy tắc cấp quyền truy cập vào nhãn đó là cần thiết. Thêm nhãn vào các tệp ngữ cảnh thích hợp.
  7. Xác định những miền/quy trình cần có miền bảo mật riêng. Có thể bạn cần phải viết một chính sách hoàn toàn mới cho từng đối tượng. Tất cả ví dụ: dịch vụ được tạo từ init sẽ có của bạn. Các lệnh sau đây giúp hiển thị những lệnh vẫn đang chạy (nhưng TẤT CẢ các dịch vụ đều cần được đối xử 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. Cung cấp cho chúng một miền sớm trong quá trình phát triển để tránh thêm quy tắc vào init hoặc gây nhầm lẫn quyền truy cập init với các quyền truy cập trong chính sách của chúng.
  9. Thiết lập BOARD_CONFIG.mk để sử dụng các biến BOARD_SEPOLICY_*. Hãy xem README trong system/sepolicy để biết thông tin chi tiết về cách thiết lập.
  10. Kiểm tra tệp init.device.rc và fstab.device và hãy đảm bảo mọi lần sử dụng mount đều tương ứng với có nhãn hệ thống tệp hoặc tuỳ chọn context= mount là đã chỉ định.
  11. Xem xét từng lần từ chối và tạo chính sách SELinux để xử lý từng từ chối đúng cách. Xem các ví dụ trong phần Tuỳ 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 đó để tuỳ chỉnh theo ý mình. Để biết thêm thông tin về chiến lược chính sách và tìm hiểu kỹ hơn về một số bước này, hãy xem phần Viết chính sách SELinux.

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

Sau đây là ví dụ cụ thể về những chỗ khai thác cần xem xét khi tự tạo phần mềm và các chính sách SELinux được liên kết:

Đường liên kết tượng trưng: Vì đường 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 hành vi khai thác. Ví dụ: một số đặc quyền thành phần, chẳng hạn như init, thay đổi quyền của một số tệp nhất định, đôi khi quá cởi mở.

Sau đó, kẻ tấn công có thể thay thế các tệp đó bằng đường 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 đè các tệp tuỳ ý. Nhưng nếu bạn biết ứng dụng không bao giờ truyền tải đường liên kết tượng trưng, bạn có thể cấm ứng dụng làm như vậy bằng SELinux.

Tệp hệ thống: Hãy xem xét lớp tệp hệ thống mà chỉ máy chủ hệ thống mới được sửa đổi. Tuy nhiên, vì netd, initvold chạy dưới dạng thư mục gốc, nên các thư mục này có thể truy cập vào các tệp hệ thống đó. Vì vậy, nếu netd bị xâm nhập, tính năng này có thể xâm phạm các tệp đó và có thể là chính máy chủ hệ thống.

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

Dữ liệu ứng dụng: Một ví dụ khác là lớp hàm phải chạy dưới dạng thư mục gốc nhưng không truy cập vào dữ liệu ứng dụng. Điều này cực kỳ hữu ích vì bạn có thể đưa ra các xác nhận trên nhiều phạm vi, chẳng hạn như một số miền 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 tệp mà miền liên kết có thể thực hiện setattr. Những việc nằm ngoài phạm vi đó có thể bị cấm đối với những thay đổi này, thậm chí cả thư mục gốc. Vì vậy, một ứng dụng có thể chạy chmodchown so với các ứng dụng được gắn nhãn app_data_files nhưng không phải shell_data_files hoặc system_data_files.