2 điểm bởi GN⁺ 2024-08-05 | 1 bình luận | Chia sẻ qua WhatsApp

Clang vs. Clang: Đừng làm Clang nổi giận

  • Đây là một bài blog về một thí nghiệm liên quan đến Clang
  • Khi xem các thay đổi gần đây của LLVM và GCC liên quan đến tối ưu hóa trình biên dịch, có thể thấy chúng bao gồm tối ưu hóa, kiểm thử tối ưu hóa, sửa kiểm thử và sửa lỗi
  • Các tác giả trình biên dịch thường không muốn chịu trách nhiệm về những lỗi do chính họ đưa vào
  • Tối ưu hóa trình biên dịch không đóng góp nhiều vào việc cải thiện hiệu năng thực tế

Vấn đề của tối ưu hóa trình biên dịch

  • Trường hợp trình biên dịch được tối ưu hóa thực sự cải thiện hiệu năng là rất hiếm
  • Ví dụ, bản triển khai avx2 của kyber768 nhanh hơn gấp 4 lần so với mã được biên dịch bằng trình biên dịch đã tối ưu hóa
  • Theo định luật của Todd A. Proebsting, tối ưu hóa trình biên dịch hầu như không đóng góp vào hiệu năng tính toán
  • Kết quả benchmark của Arseny Kapoulkine cũng đi đến kết luận tương tự

Vấn đề bảo mật

  • Trình biên dịch được tối ưu hóa có thể gây ra không chỉ các lỗi truyền thống mà còn cả các vấn đề bảo mật như rò rỉ timing
  • Theo một bài báo EuroS&P năm 2018, việc nâng cấp trình biên dịch có thể mở ra các kênh timing và khiến mã bảo mật trở nên dễ bị tấn công
  • Đã có báo cáo về một cuộc tấn công timing thành công trên mã tham chiếu Kyber khi mã được biên dịch với tùy chọn tối ưu hóa của Clang 15 trở lên

Công cụ TIMECOP

  • TIMECOP 2 được tích hợp trong framework kiểm thử mật mã SUPERCOP và tự động quét các nhánh điều kiện được dẫn xuất từ bí mật
  • Khác biệt giữa TIMECOP 1 và TIMECOP 2: TIMECOP 2 tự động đánh dấu đầu ra RNG là bí mật và chạy trên nhiều lõi

Viết mã constant-time

  • Một bài nói về cách viết mã constant-time đã được thực hiện vào tháng 7 năm 2024
  • Giải thích các hàm constant-time được cung cấp trong libmceliece và SUPERCOP
  • Ví dụ, hàm crypto_uint32_bitmod_mask(x,j) khiến trình biên dịch không thể nhận ra kết quả 1 bit

Ngăn ngừa vấn đề tối ưu hóa trình biên dịch

  • Một trong những cách ngăn trình biên dịch đưa vào rò rỉ timing là phân phối thư viện dưới dạng ngôn ngữ assembly
  • Tuy nhiên, ngôn ngữ assembly có thể khiến việc kiểm toán tính đúng đắn của phần mềm trở nên khó khăn hơn
  • Tác giả đang tìm cách nhanh chóng đưa mã phòng chống rò rỉ timing vào các mã nguồn như C, C++

Bản vá clang-vs-clang

  • Một bản vá đã được viết cho công cụ tối ưu hóa LLVM để quét &1>>31 rồi in ra cảnh báo
  • Ví dụ, cảnh báo sẽ được in ra với đoạn mã x >>= 31

Kết luận

  • Tối ưu hóa trình biên dịch không đóng góp nhiều vào cải thiện hiệu năng và có thể gây ra vấn đề bảo mật
  • Cần sử dụng các công cụ như TIMECOP để viết mã constant-time và ngăn ngừa các vấn đề từ tối ưu hóa trình biên dịch

Tóm tắt của GN⁺

  • Bài viết này nói về các vấn đề và rủi ro bảo mật của tối ưu hóa trình biên dịch
  • Bài viết nhấn mạnh rằng tối ưu hóa trình biên dịch không đóng góp nhiều vào cải thiện hiệu năng thực tế và có thể gây ra vấn đề bảo mật
  • Bài viết giới thiệu công cụ TIMECOP và cách viết mã constant-time như những phương pháp để ngăn ngừa vấn đề bảo mật
  • Bài viết cũng đề xuất cách phân phối thư viện bằng ngôn ngữ assembly để ngăn ngừa các vấn đề do tối ưu hóa trình biên dịch
  • Các dự án khác trong lĩnh vực liên quan gồm có các trình biên dịch tập trung vào bảo mật như FaCT và Jasmin

1 bình luận

 
GN⁺ 2024-08-05
Ý kiến Hacker News
  • Tác giả trình biên dịch không chịu trách nhiệm về các lỗi phát sinh do tối ưu hóa

    • Theo tiêu chuẩn ngôn ngữ, những lỗi như vậy được xem là lỗi của lập trình viên
    • Đây là bằng chứng cho thấy đó không phải là lỗi
  • Đồng ý với quan điểm của Bernstein, nhưng đôi khi ông ấy đi sai hướng

    • Lợi ích của tối ưu hóa khác nhau tùy theo trường hợp sử dụng
    • Có ý kiến phàn nàn rằng trình biên dịch C không xét đến ngữ nghĩa không thể biểu đạt bằng ngôn ngữ
    • Có thể tóm gọn thành kết luận: "Hãy dùng một ngôn ngữ có thể biểu đạt ngữ nghĩa bạn cần"
  • C và C++ không phù hợp để viết các thuật toán cần bảo đảm thời gian hằng số

    • Tiêu chuẩn hầu như không có khái niệm thời gian thực
    • Đổ lỗi cho các nhà phát triển trình biên dịch là đi sai hướng
  • Trên CPU Intel, clang hay bất kỳ thứ gì khác đều không thể sinh mã đúng trong user mode

    • Không thể thiết lập DOITM
  • Không đồng ý với nhận định rằng tác giả trình biên dịch không chịu trách nhiệm về lỗi

    • Đây là sự hiểu sai cơ bản về "undefined behavior" của C
  • clang có thuộc tính clang::optnone để tắt tối ưu hóa theo từng hàm

    • GCC có thuộc tính gnu::optimize để đặt mức tối ưu hóa
    • clang::no_builtins vô hiệu hóa tối ưu hóa memcpy và memset
  • C có quá nhiều undefined behavior nên có thể sẽ chuyển sang ngôn ngữ khác

    • Trong Python, thứ tự của đối tượng set không quan trọng
    • Trình biên dịch C phân tích các mẫu mã để cố gắng tối ưu hóa
    • Điều này có thể mang lại hiệu năng tốt hơn theo cách tương tự như cách kính thiên văn Hubble được khắc phục sự cố
  • Đồng ý với mục tiêu của các chuyên gia mật mã, nhưng trình biên dịch đa dụng không tính đến điều đó

    • Có thể cần các trình biên dịch chuyên biệt
  • Đúng là một số ngôn ngữ và trình biên dịch không phù hợp để viết các routine mật mã thời gian hằng số

    • Nhưng kết luận rằng mọi trình biên dịch và ngôn ngữ ngoài assembly đều tệ là sai
    • Nên viết một trình biên dịch và ngôn ngữ chuyên biệt miền đơn giản
  • Trong ví dụ về một hàm cụ thể, đầu vào SIZE_T_MAX gây ra undefined behavior

    • Có nhiều lỗi kiểu này, nhưng trên thực tế chúng không quan trọng lắm