Reptar: lỗ hổng FSRM/REX trên CPU Intel
(lock.cmpxchg8b.com)- Trên một số bộ xử lý Intel, khi
rep movskết hợp với tiền tốrex.rtrùng lặp dưới tối ưu hóa FSRM, CPU có thể rơi vào trạng thái “glitch” nằm ngoài các quy tắc hoạt động bình thường - Nguyên nhân đến từ cơ chế giải mã tiền tố khá lỏng lẻo của x86, và việc tiền tố
rexvốn lẽ ra không có ý nghĩa trong các lệnh dùng toán hạng ngầm nhưmovsblại đi vào một nhánh tối ưu hóa cụ thể - Pipeline kiểm chứng của Google đã phát hiện kết quả không thể dự đoán trong tổ hợp này vào tháng 8/2023, đồng thời quan sát thấy hiện tượng nhảy nhánh bất ngờ, bỏ qua nhánh vô điều kiện, và ghi nhận bất thường con trỏ lệnh của
xsavevàcall - Khi nhiều lõi cùng kích hoạt lỗi này đồng thời, có thể xảy ra machine check exception và hệ thống bị treo; lỗi cũng tái hiện được bên trong guest VM không đặc quyền nên đặc biệt quan trọng với môi trường đám mây
- Intel đã phát hành bản cập nhật microcode cho các bộ xử lý bị ảnh hưởng; nếu không thể cập nhật, có thể tắt fast strings trong
IA32_MISC_ENABLE, nhưng sẽ phải đánh đổi bằng suy giảm hiệu năng lớn
Tiền tố x86 và rep movsb
rep movsblà cách làm quen thuộc trong x86 để di chuyển bộ nhớ: khi đã thiết lập nguồn, đích, hướng và số lượng, bộ xử lý sẽ tự xử lý việc sao chép lặp lại- Lệnh thực tế là
movsb, cònreplà tiền tố (prefix) làm cho lệnh đó được lặp lại nhiều lần - Việc giải mã lệnh của x86 tương đối lỏng lẻo nên ngay cả khi có các tiền tố vô nghĩa hoặc xung đột, chúng thường vẫn bị bỏ qua
- Trình biên dịch có thể dùng các tiền tố dư thừa như vậy để đệm một lệnh đơn đến đúng biên căn chỉnh mong muốn
rex,vex,evexlà các tiền tố làm thay đổi cách giải mã của lệnh phía sau
Tổ hợp có rex gây ra vấn đề
- i386 có 8 thanh ghi đa dụng nên có thể chỉ định thanh ghi bằng 3 bit, nhưng x86-64 có 16 thanh ghi đa dụng nên cần thêm bit bổ sung
- Tiền tố
rexcung cấp các bit dư mà lệnh tiếp theo có thể dùng khi mã hóa toán hạng- Thường được viết là
rex.rxb, trong đó các bitb,x,r,wcó thể được đặt tùy chọn
- Thường được viết là
movsbcó các toán hạng đều là ngầm định, không được ghi tường minh trong lệnh, nên các bitrextrongrex.rxb rep movsblẽ ra phải vô nghĩa- Thông thường bộ xử lý sẽ âm thầm bỏ qua các tiền tố
rexnhư vậy, nhưng trên những hệ thống hỗ trợ fast short repeat move, tổ hợp này lại dẫn đến lỗ hổng
FSRM và các bộ xử lý bị ảnh hưởng
- FSRM là tính năng được giới thiệu từ Ice Lake để khắc phục giới hạn xử lý chuỗi ngắn của ERMS
- ERMS (enhanced repeat move/store) xử lý việc căn chỉnh bộ đệm và ghi rộng bằng microcode để tăng tốc mã
rep movsbhiện có- Chi phí thiết lập ban đầu khá lớn nên không phù hợp với các chuỗi rất ngắn
- FSRM là tính năng nhằm xử lý nhanh hơn các thao tác di chuyển ngắn 128 byte trở xuống
- Có thể kiểm tra hỗ trợ bằng cờ
fsrmtrong dòngflagscủa/proc/cpuinfo - Ví dụ các bộ xử lý có FSRM gồm:
- Ice Lake
- Rocket Lake
- Tiger Lake
- Raptor Lake
- Alder Lake
- Sapphire Rapids
- Danh sách này không đầy đủ; để xem toàn bộ, cần tham khảo advisory INTEL-SA-00950 của Intel
Phát hiện và tái hiện
- Pipeline kiểm chứng của Google dùng kỹ thuật Oracle Serialization để chạy hai dạng của cùng một chương trình được sinh ngẫu nhiên rồi so sánh xem trạng thái cuối có giống nhau hay không
- Giải thích liên quan có trong bài trước: Oracle Serialization
- Vào tháng 8/2023, khi thêm tiền tố
rex.rtrùng lặp vàorep movsđược tối ưu hóa bởi FSRM, kết quả không thể dự đoán đã xuất hiện - Các hành vi bất thường được quan sát gồm:
- Nhảy đến vị trí không mong muốn
- Bỏ qua nhánh vô điều kiện
- Con trỏ lệnh (instruction pointer) không được ghi chính xác trong lệnh
xsavehoặccall - Trình gỡ lỗi báo cáo các trạng thái bất khả thi
- Nếu nhiều lõi cùng kích hoạt lỗi này, bộ xử lý có thể báo machine check exception và dừng hoạt động
- Lỗi cũng có thể tái hiện từ bên trong guest VM không đặc quyền, khiến đây trở thành vấn đề bảo mật quan trọng với nhà cung cấp đám mây
- Công cụ tái hiện và tài liệu nghiên cứu được công bố trong security research repository của Google
- Một bản mirror cục bộ của công cụ
icebreakcũng được cung cấp tại icebreak.tar.gz
- Một bản mirror cục bộ của công cụ
icebreakthử tái hiện lỗi bằng cách chỉ định các cặp lõi khác nhau- Trên hệ thống không bị ảnh hưởng, chương trình sẽ không in gì, giống như vòng lặp vô hạn
- Trên hệ thống bị ảnh hưởng, mỗi lần tái hiện thành công sẽ in ra
. - Trên các lõi sibling SMT có thể quan sát thấy nhảy nhánh ngẫu nhiên
- Trên các lõi sibling SMP trong cùng package có thể quan sát thấy machine check
- Nếu không chỉ định hai lõi khác nhau, có thể sẽ cần một hammer thread
Nguyên nhân khả dĩ và tác động quan sát được
- Do cơ chế hoạt động microcode của các hệ thống hiện đại không được công khai, nguyên nhân gốc chỉ có thể được bàn đến dưới dạng giả thuyết dựa trên quan sát
- CPU về lớn được chia thành frontend và backend
- Frontend lấy và giải mã lệnh để tạo ra μops
- Backend thực thi lệnh ngoài thứ tự, lưu kết quả trong ROB (reorder buffer) rồi hoàn tất
- Có vẻ lỗi này khiến frontend tính sai kích thước của lệnh
movsb, từ đó dẫn tới trạng thái mà các mục ROB phía sau bị gắn với địa chỉ sai - Trong trạng thái đó, một tình huống hỗn loạn xảy ra khi con trỏ lệnh bị tính toán sai
- Hệ thống cuối cùng vẫn có thể tự phục hồi về trạng thái nhất quán nội bộ, nhưng các kết quả trung gian có thể bị sai
- Nếu nhiều lõi SMT hoặc SMP cùng lúc rơi vào trạng thái này, có thể gây hỏng hóc trạng thái vi kiến trúc ở mức đủ để buộc phát sinh machine check
- Trạng thái hệ thống có thể bị làm hỏng đến mức sinh ra machine check, và trong quá trình thực thi của các tiến trình được lập lịch trên các lõi sibling SMT, có thể quan sát được hiện tượng nhiễu giữa các luồng
- Chưa xác nhận được liệu có thể điều khiển sự hỏng hóc này đủ chính xác để leo thang đặc quyền hay không
Cách ứng phó
- Intel đã phát hành microcode cập nhật cho mọi bộ xử lý bị ảnh hưởng tại INTEL-SA-00950
- Nhà cung cấp hệ điều hành hoặc BIOS có thể đã phát hành bản cập nhật tương ứng
- Nếu không thể cập nhật, có thể vô hiệu hóa fast strings thông qua thanh ghi theo model
IA32_MISC_ENABLE - Việc tắt fast strings gây suy giảm hiệu năng lớn, nên không nên dùng trừ khi thực sự cần thiết
Tài liệu về các lỗi CPU liên quan
- Google đang công khai các lỗi CPU mà họ phát hiện; một số tài liệu vẫn đáng đọc ngay cả khi không có tác động bảo mật
- Ví dụ:
- movlps just doesn’t work: trường hợp
movlpskhông hoạt động - registers can sometimes roll back: trường hợp thanh ghi đôi khi quay lui về giá trị trước đó
- movlps just doesn’t work: trường hợp
1 bình luận
Ý kiến trên Hacker News
Bài liên quan: https://cloud.google.com/blog/products/identity-security/goo...
Nội dung lấy từ https://news.ycombinator.com/item?id=38268043, nhưng phần bình luận đã được gộp vào đây
Đọc bài này khiến tôi nhận ra mình biết ít thế nào về phần cứng mà phần mềm của mình đang chạy trên đó
Bài viết nói “tiền tố (prefix) cho phép bật hoặc tắt các tính năng để thay đổi hành vi của lệnh”, nên tôi thắc mắc tại sao lại cần “tiền tố” để bật/tắt tính năng
Có phải dùng để chuyển đổi tính năng động mà không cần vào BIOS không?
Tiền tố REP là phổ biến nhất, có vai trò cho phép lặp cùng một lệnh với số lần biến đổi
Số lần lặp được lấy từ thanh ghi CX, giúp những vòng lặp phổ biến như di chuyển đối tượng trong bộ nhớ trở nên rất ngắn
Hàm memcpy thường được inline thành một lệnh REP MOVS, kèm thêm lệnh sao chép count vào CX nếu cần
Tiền tố REX cũng khá phổ biến vì chương trình 64-bit thường xuyên xử lý giá trị và địa chỉ 64-bit
Không tiền tố nào bật/tắt thứ có thể cấu hình toàn cục bằng BIOS hay tương tự; tất cả chỉ chỉ định việc lệnh kế tiếp phải làm
Với những chế độ định địa chỉ hiếm dùng, sẽ có “tiền tố segment” để dùng segment khác DS; còn tiền tố “REX” của x86_64 đã thêm bit vào trường thanh ghi để có thể dùng 16 thanh ghi đa dụng
Tương tự, tiền tố “LOCK”, dù đặc tả ban đầu khá kém, khiến một số thao tác bộ nhớ trở nên nguyên tử đối với phần còn lại của hệ thống, chẳng hạn triển khai compare-and-set bằng “LOCK CMPXCHG”
Các kiến trúc CPU khác cũng biểu diễn những thao tác như vậy, nhưng thường đưa vào không gian lệnh sẵn có, nên cần nhiều bit hơn để biểu diễn mọi lệnh
Riêng tiền tố “REP” gây vấn đề ở đây gần như là ngoại lệ: đó là tiền tố lặp bằng microcode còn sót lại từ thời rất xưa
Tuy vậy, nó vẫn biểu diễn các thao tác nhạy cảm về hiệu năng ngày nay như memset/memmove, nên các hãng CPU vẫn có lý do để tiếp tục tối ưu, và có vẻ lỗi lần này phát sinh trong quá trình đó
Vấn đề lớn nhất là nó đã “tận dụng hiệu quả” không gian mã hóa của lệnh
Về sau, khi có lệnh mới — tệ hơn nữa là có thêm thanh ghi — người ta phải tìm cách nhét các biến thể lệnh mới vào, và cách đó là gắn thêm tiền tố
Mỗi lần mở rộng tập lệnh, người ta lại khoét một phần không gian opcode để nhét tiền tố mới vào
Nhìn việc Intel năm nay lại đề xuất một cách mới khác, có vẻ xu hướng này sẽ còn tiếp diễn
Quá trình chẩn đoán làm tôi nhớ đến chuyện đã xảy ra khi qemu gặp repz ret: https://repzret.org/p/repzret/
Theo quy định của HN, tôi nghĩ nên cấm những tiêu đề kiểu này
Nó hoàn toàn không cho biết liên kết là gì, còn URL thì lại càng gây rối hơn
Nếu tiêu đề vô nghĩa như vậy, tôi nghĩ người đăng nên thêm một mô tả ngắn
Tôi đã thấy khi tiêu đề chứa quá nhiều ngữ cảnh, mọi người không nhấp vào liên kết mà chỉ chỉnh sửa mối quan tâm của mình trong phần bình luận như cách phản ứng với tweet
HN chọn điểm cân bằng nhằm khuyến khích sự tò mò trí tuệ và việc nhấp vào liên kết
Ngay cả khi tiêu đề mơ hồ khiến bạn từ chối nhấp vào liên kết, ít nhất bạn vẫn sẽ phản hồi những người đã nhấp, nên tôi nghĩ như vậy tốt hơn nhiều nơi khác trên Internet
Những bài không có phần thưởng đủ để biện minh cho tiêu đề mơ hồ và dí dỏm, không giống bài này, sẽ rớt khỏi trang nhất
Bài viết rất hay
Tôi gần như không biết gì về lập trình assembly và tập lệnh Intel, cũng như vi kiến trúc, nhưng vẫn theo dõi được phần giải thích và có cảm giác mình hiểu đại khái chuyện gì đang xảy ra ở đây
Không biết có ai biết CPU AMD có bị ảnh hưởng không?
Nếu vấn đề thực sự là bộ xử lý nhầm lẫn về độ dài lệnh, thì việc có thể sửa bằng microcode mà không làm giảm hiệu năng nhiều là điều rất ấn tượng
Trực giác của tôi có thể hoàn toàn sai, nhưng tôi từng nghĩ việc tính độ dài lệnh hẳn sẽ được tổng hợp trực tiếp bằng các cổng logic
Nghĩ lại thì có thể bộ giải mã uOP về mặt phần cứng vẫn ổn, còn một routine sao chép được tối ưu bằng microcode đang cố suy luận điều không đúng về luồng uOP
Ví dụ như “à, đây là rep mov, vậy để lặp thì chỉ cần nhảy lùi lại hai uOP là được”
Có lẽ đội CPU của Intel sẽ không công bố đến mức chi tiết như vậy
Tôi không rõ “ERMS” và “FSRM” là gì, và trên Google cũng gần như không thấy tài liệu nào ổn
Tôi thắc mắc liệu chúng chỉ là các cờ CPUID cho biết có thể dùng rep movsb với hiệu năng cao nhất thay vì các triển khai SSE memcpy đã tối ưu, hay chúng là một kiểu mã hóa hoặc tiền tố đặc biệt nào đó làm cho rep movsb nhanh hơn
Nếu là trường hợp sau thì tôi cũng không hiểu vì sao lại cần, và fsrm được tận dụng như thế nào
Có vẻ ERMS từng là phương án thay thế rẻ hơn cho AVX, còn FSRM là phiên bản tốt hơn cho các khối ngắn
“Celeron và Pentium Kaby Lake ra mắt năm 2017, tức các phiên bản giá rẻ của những bộ xử lý về sau, không có AVX để dùng cho sao chép bộ nhớ nhanh, nhưng có Enhanced REP MOVSB
Và một số kiến trúc di động/tiết kiệm điện của Intel ra mắt từ năm 2018 không dựa trên SkyLake, nhưng khi dùng REP MOVSB thì sao chép được số byte trên mỗi chu kỳ CPU nhiều hơn khoảng gấp đôi so với các vi kiến trúc thế hệ trước”
“Trước Fast Short REP MOV(FSRM) của vi kiến trúc Ice Lake, Enhanced REP MOVSB(ERMSB) chỉ nhanh hơn sao chép bằng AVX hoặc sao chép bằng thanh ghi đa dụng khi kích thước khối tối thiểu là 256 byte
Với các khối dưới 64 byte, chi phí khởi động nội bộ của ERMSB cao, khoảng 35 chu kỳ, nên chậm hơn nhiều; tính năng FSRM nhằm mục đích làm cho cả các khối dưới 128 byte cũng nhanh”
[1] https://stackoverflow.com/a/43837564
[2] http://www.intel.com/content/dam/www/public/us/en/documents/...
Việc chọn lệnh và lập lịch tối ưu có thể được thực hiện tĩnh ở thời điểm biên dịch, hoặc động ở runtime bằng cách chọn một trong nhiều hàm thư viện, hay bằng JIT
Để phát hiện ở runtime lịch lệnh nào là tối ưu, cần biết CPU thực tế
Có thể duy trì một bảng cho mọi mẫu CPU, nhưng cũng có thể hỏi hệ điều hành xem CPU đang chạy có triển khai tối ưu hóa đó hay không
Linux cần được vá để CPU có thể báo rằng nó đã triển khai tối ưu hóa đó
https://www.phoronix.com/news/Intel-5.6-FSRM-Memmove
Tôi thấy khuyến cáo của Intel [1] viết như sau
Intel cảm ơn các nhân viên Intel đã tự phát hiện vấn đề này, đồng thời cũng cảm ơn các nhân viên Google đã báo cáo vấn đề này
[1] https://www.intel.com/content/www/us/en/security-center/advi...
Khuyến cáo của Intel có phần mô tả tác động cũng đáng tham khảo: https://www.intel.com/content/www/us/en/security-center/advi...
“Một chuỗi lệnh của bộ xử lý trên một số bộ xử lý Intel(R) có thể gây ra hành vi ngoài dự kiến, cho phép người dùng đã xác thực có quyền truy cập cục bộ leo thang đặc quyền, tiết lộ thông tin hoặc gây từ chối dịch vụ”
Konrad Magnusson thuộc đội Victoria 3 của Paradox Interactive đã tìm thấy điều gì đó liên quan tới việc này và mimalloc: https://github.com/microsoft/mimalloc/issues/807
Tôi không chắc có hoàn toàn liên quan hay không, nhưng có khả năng