Google cam kết thúc đẩy công bằng chủng tộc cho Cộng đồng người da đen. Xem cách thực hiện.

Viết chính sách SELinux

Dự án nguồn mở Android (AOSP) cung cấp chính sách cơ sở vững chắc cho các ứng dụng và dịch vụ phổ biến trên tất cả các thiết bị Android. Những người đóng góp cho AOSP thường xuyên cải tiến chính sách này. Chính sách cốt lõi dự kiến ​​sẽ chiếm khoảng 90–95% chính sách cuối cùng trên thiết bị với các tùy chỉnh dành riêng cho thiết bị chiếm 5–10% còn lại. Bài viết này tập trung vào các tùy chỉnh dành riêng cho thiết bị này, cách viết chính sách dành riêng cho thiết bị và một số cạm bẫy cần tránh trong quá trình thực hiện.

Mang lên thiết bị

Trong khi viết chính sách dành riêng cho thiết bị, hãy làm theo các bước sau.

Chạy ở chế độ cho phép

Khi một thiết bị ở chế độ cho phép , các từ chối được ghi lại nhưng không được thực thi. Chế độ cho phép quan trọng vì hai lý do:

  • Chế độ cho phép đảm bảo rằng việc đưa ra chính sách không làm chậm trễ các tác vụ khởi động thiết bị ban đầu khác.
  • Một sự từ chối được thực thi có thể che dấu những sự từ chối khác. Ví dụ: truy cập tệp thường đòi hỏi phải tìm kiếm thư mục, mở tệp, sau đó đọc tệp. Trong chế độ thực thi, chỉ xảy ra từ chối tìm kiếm thư mục. Chế độ cho phép đảm bảo tất cả các từ chối đều được nhìn thấy.

Cách đơn giản nhất để đưa một thiết bị vào chế độ cho phép là sử dụng dòng lệnh kernel . Điều này có thể được thêm vào tệp BoardConfig.mk của thiết bị: platform/device/<vendor>/<target>/BoardConfig.mk . Sau khi sửa đổi dòng lệnh, hãy thực hiện make clean , sau đó make bootimage và flash hình ảnh khởi động mới.

Sau đó, xác nhận chế độ cho phép với:

adb shell getenforce

Hai tuần là khoảng thời gian hợp lý để ở chế độ cho phép toàn cầu. Sau khi giải quyết phần lớn các từ chối, hãy quay lại chế độ thực thi và xử lý lỗi khi chúng xuất hiện. Các miền vẫn tạo ra từ chối hoặc dịch vụ vẫn đang trong quá trình phát triển nặng có thể tạm thời được đưa vào chế độ cho phép, nhưng hãy chuyển chúng trở lại chế độ thực thi càng sớm càng tốt.

Thực thi sớm

Trong chế độ thực thi, các từ chối đều được ghi lại và thực thi. Cách tốt nhất là đưa thiết bị của bạn vào chế độ thực thi càng sớm càng tốt. Việc chờ đợi để tạo và thực thi chính sách dành riêng cho thiết bị thường dẫn đến sản phẩm có lỗi và trải nghiệm người dùng không tốt. Bắt đầu đủ sớm để tham gia dogfooding và đảm bảo kiểm tra đầy đủ các chức năng trong việc sử dụng trong thế giới thực. Bắt đầu sớm đảm bảo các mối quan tâm về bảo mật thông báo cho các quyết định thiết kế. Ngược lại, việc cấp quyền chỉ dựa trên những từ chối quan sát được là một cách tiếp cận không an toàn. Sử dụng thời gian này để thực hiện kiểm tra bảo mật của thiết bị và tập tin các lỗi chống lại các hành vi không được phép.

Xóa hoặc xóa chính sách hiện có

Có một số lý do chính đáng để tạo chính sách dành riêng cho thiết bị từ đầu trên một thiết bị mới, bao gồm:

Giải quyết từ chối các dịch vụ cốt lõi

Các từ chối do các dịch vụ cốt lõi tạo ra thường được giải quyết bằng cách gắn nhãn tệp. Ví dụ:

avc: denied { open } for pid=1003 comm=”mediaserver” path="/dev/kgsl-3d0”
dev="tmpfs" scontext=u:r:mediaserver:s0 tcontext=u:object_r:device:s0
tclass=chr_file permissive=1
avc: denied { read write } for pid=1003 name="kgsl-3d0" dev="tmpfs"
scontext=u:r:mediaserver:s0
tcontext=u:object_r:device:s0 tclass=chr_file permissive=1

hoàn toàn được giải quyết bằng cách ghi nhãn đúng cách /dev/kgsl-3d0 . Trong ví dụ này, tcontextdevice . Điều này đại diện cho một ngữ cảnh mặc định trong đó mọi thứ trong /dev đều nhận được nhãn “ thiết bị ” trừ khi một nhãn cụ thể hơn được chỉ định. Chỉ cần chấp nhận đầu ra từ Audit2allow ở đây sẽ dẫn đến một quy tắc không chính xác và quá dễ dãi.

Để giải quyết loại vấn đề này, hãy đặt cho tệp một nhãn cụ thể hơn, trong trường hợp này là gpu_device . Không cần thêm quyền vì máy chủ trung gian đã có các quyền cần thiết trong chính sách cốt lõi để truy cập gpu_device.

Các tệp khác dành riêng cho thiết bị phải được gắn nhãn với các loại được xác định trước trong chính sách cốt lõi:

Nói chung, việc cấp quyền cho các nhãn mặc định là sai. Nhiều quyền trong số này không được phép theo quy tắc neverallow , nhưng ngay cả khi không được phép một cách rõ ràng, phương pháp hay nhất là cung cấp một nhãn cụ thể.

Gắn nhãn các dịch vụ mới và địa chỉ từ chối

Các dịch vụ do Init khởi chạy bắt buộc phải chạy trong các miền SELinux của riêng chúng. Ví dụ sau đặt dịch vụ “foo” vào miền SELinux của chính nó và cấp cho nó quyền.

Dịch vụ được khởi chạy trong init. device .rc tệp dưới dạng:

service foo /system/bin/foo
    class core
  1. Tạo một miền mới "foo"

    Tạo tệp device/ manufacturer / device-name /sepolicy/foo.te với nội dung sau:

    # foo service
    type foo, domain;
    type foo_exec, exec_type, file_type;
    
    init_daemon_domain(foo)
    

    Đây là mẫu ban đầu cho miền foo SELinux, mà bạn có thể thêm các quy tắc dựa trên các hoạt động cụ thể được thực hiện bởi tệp thực thi đó.

  2. Nhãn /system/bin/foo

    Thêm phần sau vào device/ manufacturer / device-name /sepolicy/file_contexts :

    /system/bin/foo   u:object_r:foo_exec:s0
    

    Điều này đảm bảo tệp thực thi được gắn nhãn thích hợp để SELinux chạy dịch vụ trong miền thích hợp.

  3. Xây dựng và flash hình ảnh khởi động và hệ thống.
  4. Tinh chỉnh các quy tắc SELinux cho miền.

    Sử dụng từ chối để xác định các quyền cần thiết. Công cụ Aud2allow cung cấp các nguyên tắc tốt, nhưng chỉ sử dụng nó để cung cấp thông tin cho việc viết chính sách. Đừng chỉ sao chép đầu ra.

Chuyển về chế độ thực thi

Bạn có thể khắc phục sự cố ở chế độ cho phép, nhưng hãy chuyển về chế độ thực thi càng sớm càng tốt và cố gắng duy trì ở đó.

Lỗi thường gặp

Dưới đây là một số giải pháp cho những lỗi phổ biến xảy ra khi viết các chính sách dành riêng cho thiết bị.

Lạm dụng phủ định

Quy tắc ví dụ sau giống như khóa cửa trước nhưng vẫn để cửa sổ mở:

allow { domain -untrusted_app } scary_debug_device:chr_file rw_file_perms

Mục đích rất rõ ràng: mọi người trừ các ứng dụng của bên thứ ba có thể có quyền truy cập vào thiết bị gỡ lỗi.

Quy tắc này có sai sót trong một số cách. Việc loại trừ untrusted_app là điều không thể tránh khỏi bởi vì tất cả các ứng dụng có thể chạy các dịch vụ trong miền isolated_app theo tùy chọn. Tương tự như vậy, nếu các miền mới cho ứng dụng của bên thứ ba được thêm vào AOSP, chúng cũng sẽ có quyền truy cập vào scary_debug_device . Quy tắc quá dễ dãi. Hầu hết các miền sẽ không được hưởng lợi khi có quyền truy cập vào công cụ gỡ lỗi này. Quy tắc đáng lẽ phải được viết để chỉ cho phép các miền yêu cầu quyền truy cập.

Tính năng gỡ lỗi trong sản xuất

Các tính năng gỡ lỗi không được xuất hiện trên các phiên bản sản xuất cũng như chính sách của chúng.

Giải pháp thay thế đơn giản nhất là chỉ cho phép tính năng gỡ lỗi khi SELinux bị tắt trên các bản dựng eng / userdebug, chẳng hạn như adb rootadb shell setenforce 0 .

Một giải pháp thay thế an toàn khác là đặt quyền gỡ lỗi trong câu lệnh userdebug_or_eng .

Sự bùng nổ quy mô chính sách

Đặc điểm chính sách SEAndroid trong tự nhiên mô tả một xu hướng liên quan đến sự phát triển của các tùy chỉnh chính sách thiết bị. Chính sách dành riêng cho thiết bị phải chiếm 5–10% tổng thể chính sách đang chạy trên một thiết bị. Các tùy chỉnh trong phạm vi 20% + gần như chắc chắn chứa các miền đặc quyền và chính sách đã chết.

Chính sách lớn không cần thiết:

  • Gây ảnh hưởng lớn đến bộ nhớ khi chính sách nằm trong đĩa ram và cũng được tải vào bộ nhớ hạt nhân.
  • Gây lãng phí dung lượng ổ đĩa bằng cách yêu cầu một bộ kích thích lớn hơn.
  • Ảnh hưởng đến thời gian tra cứu chính sách thời gian chạy.

Ví dụ sau đây cho thấy hai thiết bị trong đó chính sách dành riêng cho nhà sản xuất bao gồm 50% và 40% chính sách trên thiết bị. Việc viết lại chính sách đã mang lại những cải tiến đáng kể về bảo mật mà không bị mất chức năng, như được hiển thị bên dưới. (Các thiết bị AOSP Shamu và Flounder được bao gồm để so sánh.)

Hình 1: So sánh kích thước chính sách dành riêng cho thiết bị sau khi kiểm tra bảo mật.

Hình 1 . So sánh kích thước chính sách dành riêng cho thiết bị sau khi kiểm tra bảo mật.

Trong cả hai trường hợp, chính sách đã giảm đáng kể cả về quy mô và số lượng quyền. Việc giảm quy mô chính sách gần như hoàn toàn là do loại bỏ các quyền không cần thiết, nhiều quyền trong số đó có khả năng là các quy tắc do audit2allow tạo ra đã được thêm vào chính sách một cách bừa bãi. Miền chết cũng là một vấn đề đối với cả hai thiết bị.

Cấp khả năng dac_override

Từ chối dac_override có nghĩa là quá trình vi phạm đang cố gắng truy cập vào một tệp có quyền người dùng / nhóm / thế giới unix không chính xác. Giải pháp thích hợp là hầu như không bao giờ cấp quyền dac_override . Thay vào đó, hãy thay đổi các quyền unix trên tệp hoặc quá trình . Một số miền như init , voldinstalld thực sự cần khả năng ghi đè quyền tệp unix để truy cập tệp của các quy trình khác. Xem blog của Dan Walsh để có lời giải thích sâu hơn.