Scudo

Scudo là một công cụ cấp phát bộ nhớ ở chế độ người dùng động, hay còn gọi là công cụ cấp phát vùng heap , được thiết kế để có khả năng phục hồi trước các lỗ hổng liên quan đến heap (chẳng hạn như tràn bộ đệm dựa trên heap , sử dụng sau freedouble free ) trong khi vẫn duy trì hiệu suất. Nó cung cấp các nguyên hàm phân bổ và phân bổ C tiêu chuẩn (chẳng hạn như malloc và miễn phí), cũng như các nguyên hàm C++ (chẳng hạn như mới và xóa).

Scudo có tác dụng giảm thiểu nhiều hơn là một công cụ phát hiện lỗi bộ nhớ hoàn chỉnh như addressSanitizer (ASan) .

Kể từ khi phát hành Android 11, scudo được sử dụng cho tất cả mã gốc (ngoại trừ trên các thiết bị có bộ nhớ thấp, nơi vẫn sử dụng jemalloc). Trong thời gian chạy, tất cả các phân bổ và giải phóng vùng heap gốc đều được Scudo phục vụ cho tất cả các tệp thực thi và phần phụ thuộc thư viện của chúng, đồng thời quá trình này sẽ bị hủy bỏ nếu phát hiện thấy hành vi sai trái hoặc đáng ngờ trong vùng heap.

Scudo là mã nguồn mở và là một phần của dự án trình biên dịch-rt của LLVM. Tài liệu có sẵn tại https://llvm.org/docs/ScudoHardenedAllocator.html . Thời gian chạy Scudo được cung cấp như một phần của chuỗi công cụ Android và tính năng hỗ trợ đã được thêm vào Soong và Make để cho phép dễ dàng kích hoạt bộ cấp phát ở dạng nhị phân.

Bạn có thể bật hoặc tắt tính năng giảm nhẹ bổ sung trong bộ cấp phát bằng cách sử dụng các tùy chọn được mô tả bên dưới.

Tùy chỉnh

Một số tham số của bộ cấp phát có thể được xác định trên cơ sở từng quy trình thông qua một số cách:

  • Tĩnh: Xác định hàm __scudo_default_options trong chương trình trả về chuỗi tùy chọn cần phân tích cú pháp. Hàm này phải có nguyên mẫu sau: extern "C" const char *__scudo_default_options() .
  • Động: Sử dụng biến môi trường SCUDO_OPTIONS chứa chuỗi tùy chọn cần phân tích cú pháp. Các tùy chọn được xác định theo cách này sẽ ghi đè mọi định nghĩa được thực hiện thông qua __scudo_default_options .

Lựa chọn tiếp theo đã khả thi.

Lựa chọn mặc định 64-bit mặc định 32-bit Sự miêu tả
QuarantineSizeKb 256 64 Kích thước (tính bằng KB) của vùng cách ly được sử dụng để trì hoãn việc phân bổ các khối thực tế. Giá trị thấp hơn có thể giảm mức sử dụng bộ nhớ nhưng làm giảm hiệu quả giảm thiểu; một giá trị âm rơi trở lại giá trị mặc định. Việc đặt cả giá trị này và ThreadLocalQuarantineSizeKb về 0 sẽ vô hiệu hóa hoàn toàn việc cách ly.
QuarantineChunksUpToSize 2048 512 Kích thước (tính bằng byte) mà các khối có thể được cách ly.
ThreadLocalQuarantineSizeKb 64 16 Kích thước (tính bằng KB) của bộ đệm trên mỗi luồng sử dụng để giảm tải vùng cách ly toàn cầu. Giá trị thấp hơn có thể làm giảm mức sử dụng bộ nhớ nhưng có thể làm tăng sự tranh chấp về vùng cách ly toàn cầu. Việc đặt cả cái này và QuarantineSizeKb về 0 sẽ vô hiệu hóa hoàn toàn việc cách ly.
DeallocationTypeMismatch false false Cho phép báo cáo lỗi về malloc/xóa, mới/miễn phí, mới/xóa[]
DeleteSizeMismatch true true Cho phép báo cáo lỗi về kích thước không khớp giữa kích thước mới và xóa.
ZeroContents false false Cho phép nội dung không có đoạn khi phân bổ và phân bổ.
allocator_may_return_null false false Chỉ định rằng bộ cấp phát có thể trả về null khi xảy ra lỗi có thể phục hồi, thay vì chấm dứt quá trình.
hard_rss_limit_mb 0 0 Khi RSS của tiến trình đạt đến giới hạn này, tiến trình sẽ chấm dứt.
soft_rss_limit_mb 0 0 Khi RSS của quy trình đạt đến giới hạn này, các phân bổ tiếp theo sẽ không thành công hoặc trả về giá trị null (tùy thuộc vào giá trị của allocator_may_return_null ), cho đến khi RSS quay trở lại để cho phép phân bổ mới.
allocator_release_to_os_interval_ms không áp dụng 5000 Chỉ ảnh hưởng đến bộ cấp phát 64 bit. Nếu được đặt, sẽ cố gắng giải phóng bộ nhớ không sử dụng cho HĐH nhưng không thường xuyên hơn khoảng thời gian này (tính bằng mili giây). Nếu giá trị âm, bộ nhớ sẽ không được giải phóng cho HĐH.
abort_on_error true true Nếu được đặt, công cụ sẽ gọi abort() thay vì _exit() sau khi in thông báo lỗi.

Thẩm định

Hiện tại chưa có bài kiểm tra CTS nào dành riêng cho Scudo. Thay vào đó, hãy đảm bảo rằng các bài kiểm tra CTS vượt qua dù có hoặc không bật Scudo cho một tệp nhị phân nhất định để xác minh rằng nó không ảnh hưởng đến thiết bị.

Xử lý sự cố

Nếu phát hiện sự cố không thể khắc phục, bộ cấp phát sẽ hiển thị thông báo lỗi tới bộ mô tả lỗi tiêu chuẩn và sau đó kết thúc quá trình. Dấu vết ngăn xếp dẫn đến việc chấm dứt sẽ được thêm vào nhật ký hệ thống. Đầu ra thường bắt đầu bằng Scudo ERROR: theo sau là bản tóm tắt ngắn gọn về vấn đề cùng với bất kỳ con trỏ nào.

Dưới đây là danh sách các thông báo lỗi hiện tại và nguyên nhân tiềm ẩn của chúng:

  • corrupted chunk header : Việc xác minh tổng kiểm tra tiêu đề đoạn không thành công. Điều này có thể do một trong hai nguyên nhân: tiêu đề bị ghi đè (một phần hoặc toàn bộ) hoặc con trỏ được truyền tới hàm không phải là một đoạn.
  • race on chunk header : Hai luồng khác nhau đang cố gắng thao tác cùng một tiêu đề cùng một lúc. Điều này thường là triệu chứng của tình trạng dồn đuổi hoặc thiếu khóa nói chung khi thực hiện các thao tác trên đoạn đó.
  • invalid chunk state : Đoạn không ở trạng thái mong đợi cho một thao tác nhất định, ví dụ: nó không được phân bổ khi cố gắng giải phóng nó hoặc nó không bị cách ly khi cố gắng tái chế nó. Miễn phí gấp đôi là lý do điển hình cho lỗi này.
  • misaligned pointer : Các yêu cầu căn chỉnh cơ bản được thực thi mạnh mẽ: 8 byte trên nền tảng 32 bit và 16 byte trên nền tảng 64 bit. Nếu một con trỏ được truyền tới các hàm của chúng ta không khớp với các hàm đó thì con trỏ được truyền tới một trong các hàm sẽ không được căn chỉnh.
  • allocation type mismatch : Khi tùy chọn này được bật, hàm phân bổ được gọi trên một đoạn phải khớp với loại hàm được gọi để phân bổ nó. Kiểu không khớp này có thể gây ra các vấn đề về bảo mật.
  • invalid sized delete : Khi sử dụng toán tử xóa có kích thước C++14 và kiểm tra tùy chọn được bật, sẽ có sự không khớp giữa kích thước được chuyển khi hủy phân bổ một đoạn và kích thước được yêu cầu khi phân bổ nó. Đây thường là sự cố trình biên dịch hoặc nhầm lẫn về kiểu trên đối tượng đang bị hủy phân bổ.
  • RSS limit exhausted : RSS tối đa được chỉ định tùy chọn đã bị vượt quá.

Nếu bạn đang gỡ lỗi cho chính hệ điều hành, bạn có thể sử dụng bản dựng hệ điều hành HWASan . Nếu bạn đang gỡ lỗi sự cố trong ứng dụng, bạn cũng có thể sử dụng bản dựng ứng dụng HWASan .