Tổng quan về IPC của Hubris
- Hubris sử dụng một kernel nhỏ, không phụ thuộc vào ứng dụng, và phần lớn mã nguồn (driver, logic ứng dụng, network stack, v.v.) nằm trong các tác vụ cách ly được biên dịch riêng
- Các tác vụ này có thể giao tiếp với nhau bằng hệ thống nhắn tin liên tác vụ (IPC)
- IPC của Hubris gồm 3 thao tác cốt lõi được triển khai trong kernel (RECV, SEND, REPLY)
- RECV: nhận thông điệp đến có mức ưu tiên cao nhất hoặc chặn cho đến khi có thông điệp đến
- SEND: gửi thông điệp và quyền điều khiển tới tác vụ nhận rồi dừng tác vụ gọi. Tác vụ gọi chuyển sang trạng thái chờ cho đến khi nhận được phản hồi
- REPLY: gửi phản hồi cho tác vụ trước đó đã dùng SEND để nó có thể tiếp tục chạy
Chế độ lỗi mới mẻ và thú vị
- Vì IPC vượt qua ranh giới tác vụ và các tác vụ trong Hubris là những chương trình được biên dịch riêng, cần cẩn trọng khi áp dụng cho IPC những giả định mà compiler thường đưa ra với lời gọi hàm
- Mọi tác vụ đóng vai trò máy chủ IPC trong Hubris đều phải xử lý các lỗi tiềm ẩn sau:
- Nhận thông điệp có interface và mã thao tác không phù hợp
- Nhận một bó byte không thể diễn giải thay vì kiểu thông điệp được mong đợi, hoặc nhận thông điệp quá ngắn hay quá dài
- Không nhận được vùng nhớ cần thiết (chẳng hạn vùng nhớ có thể ghi)
Trong các chương trình bình thường và đúng đắn, những tình huống này không xảy ra
- Trong các chương trình Hubris bình thường, những tình huống nêu trên không xảy ra
- Các tác vụ được liên kết với nhau bởi cấu hình của hệ thống build nên rất khó để nhầm lẫn lẫn nhau
- Client và server sử dụng mã Rust được sinh ra, nên có thể giả định rằng hệ thống kiểu hoạt động xuyên qua ranh giới tác vụ
Kernel không cho phép bất kỳ điều vô lý nào
- Trong Unix, nếu vi phạm điều kiện tiên quyết của system call thì caller sẽ nhận mã lỗi trả về, nhưng trong Hubris thì tác vụ sẽ bị hủy ngay lập tức
- Kernel Hubris truyền lỗi cho tác vụ vi phạm quy tắc của kernel thông qua khái niệm có tên là Synthetic Fault
- Trong Hubris, khi xảy ra lỗi phần cứng hoặc lỗi tổng hợp, tác vụ sẽ bị dừng ngay lập tức và không thể phục hồi
Máy chủ cũng không cho phép bất kỳ điều vô lý nào
- Thông qua system call thứ 13 và kỳ lạ nhất là REPLY_FAULT, máy chủ có thể truyền lỗi cho client
- REPLY_FAULT tương tự REPLY, nhưng thay vì gửi thông điệp và đưa tác vụ về trạng thái có thể chạy, nó truyền lỗi và dừng tác vụ
- REPLY_FAULT giúp tránh phải xử lý các lỗi IPC không cần thiết. Chương trình bình thường có thể hoạt động như thể sự cố không thể xảy ra, còn chương trình bất thường thậm chí không có cơ hội xử lý lỗi
- REPLY_FAULT cung cấp một cách mới để định nghĩa và triển khai các lỗi đặc thù ứng dụng, chẳng hạn như quy tắc kiểm soát truy cập
Ý kiến của GN⁺
- REPLY_FAULT là một cơ chế mạnh cho phép máy chủ gây ra
panic! xuyên tiến trình ở phía client mà không cần sự hợp tác từ phía client. Nhờ đó, Hubris trở thành một hệ thống rất thù địch với các chương trình độc hại
- Nhược điểm của REPLY_FAULT là việc fuzzing trở nên rất khó. Một tác vụ chaos engineering tạo IPC hay system call ngẫu nhiên sẽ bị reset ngay ở gần như mọi hành vi
- Tuy nhiên, các tác vụ Hubris bình thường không tạo thông điệp IPC một cách động, nên có thể vận hành mà không hề nhận thức được sự tồn tại của REPLY_FAULT
- Thông qua REPLY_FAULT, máy chủ có thể gây lỗi ngẫu nhiên cho client, nhưng việc đánh giá điều này vẫn chưa hoàn tất hoàn toàn
- Cách xử lý lỗi quyết liệt của Hubris giúp phát hiện lỗi từ sớm trong quá trình phát triển, và khác với mã lỗi, lỗi không thể bị phớt lờ
- Nếu dùng một phương pháp phổ quát để xử lý lỗi IPC thì ngay cả các chương trình bình thường cũng có thể phải chịu overhead không cần thiết. REPLY_FAULT có vẻ là một giải pháp thanh lịch giúp tránh điều đó, đồng thời vẫn phản ứng nghiêm khắc với các chương trình bất thường
1 bình luận
Ý kiến trên Hacker News
Tóm lại như sau:
Có lo ngại về việc liệu
REPLY_FAULTcó lan truyền theo chuỗi hay không, và các lỗ hổng phát sinh từ đóREPLY_FAULTthì A có bị kết thúc theo hay khôngSENDtạo thành cấu trúc vòng lặp thì thậm chí có thể vô tình tự kết thúc chính mìnhREPLY_FAULTcung cấp cách định nghĩa và triển khai các lỗi đặc thù của ứng dụng như kiểm soát truy cậpTrong các hệ thống mà một nhóm viết toàn bộ mã nguồn, việc loại bỏ các client đáng ngờ có thể giúp tăng tốc độ lặp
Có thể xem Hubris là một kernel cho phép server thực hiện những tác động mà client không thể tự xử lý
Hubris và Humility là những công nghệ khiến người ta muốn đào sâu, nhưng điều đó khó thực hiện vì giới hạn về thời gian và trách nhiệm
Có nhắc đến một RFC Cá tháng Tư về HTTP đề xuất mã trạng thái HTTP 499 mang nghĩa "bạn nên thấy xấu hổ"
Trích dẫn câu nói nổi tiếng của Einstein: "Hãy làm mọi thứ đơn giản nhất có thể, nhưng đừng đơn giản quá mức", và chỉ ra rằng thiết kế của Hubris đã vi phạm vế sau
Humility là một cái tên tuyệt vời cho debugger
Trên Linux, không thể trực tiếp kết thúc chương trình khác chỉ bằng socket, nhưng với quyền root thì có thể kết thúc tiến trình khác hoặc thậm chí khởi động lại máy
Điều này phần nào mâu thuẫn với triết lý quen thuộc của các hệ thống mạng: "hãy rộng lượng khi tiếp nhận và nghiêm ngặt khi phát đi"