เรื่องราวของบั๊ก Hubris: ใครกันที่ทำให้สวิตช์เครือข่ายพัง?
-
Hubris คืออะไร?
- Hubris เป็นระบบปฏิบัติการสำหรับระบบฝังตัวเชิงลึก ออกแบบมาสำหรับคอมพิวเตอร์ที่ไม่ได้ถูกมองว่าเป็นคอมพิวเตอร์ เช่น ภายในคีย์บอร์ด
- มันถูกพัฒนาขึ้นเพื่อจัดการทุกอย่างที่จำเป็นต่อการเริ่มต้นโปรเซสเซอร์ขนาดใหญ่ใน Oxide Rack
- Hubris ค่อนข้างมีเอกลักษณ์เฉพาะตัว โดยส่วนที่เกี่ยวข้องกับเรื่องนี้จะอธิบายด้านล่าง
-
ที่เกิดเหตุ
- Arjen Roodselaar เพื่อนร่วมงานผู้รับผิดชอบเฟิร์มแวร์ของสวิตช์เครือข่ายที่ Oxide กำลังทดสอบการเปลี่ยนแปลงเกี่ยวกับลำดับการจ่ายไฟและการตั้งค่านาฬิกา
- หลังจากการเปลี่ยนแปลงเล็กน้อย สวิตช์ก็เปิดไม่ติดขึ้นมาอย่างกะทันหัน
- เฟิร์มแวร์บางส่วนยังตอบสนองอยู่ แต่ส่วนสำคัญที่ดูแลลำดับการจ่ายไฟกลับหยุดทำงาน
-
ดึงประสิทธิภาพให้ได้มากขึ้นจาก RAM ที่มีจำกัด
- ไมโครคอนโทรลเลอร์ราคาประหยัดที่ใช้ Hubris มี RAM และแฟลชที่จำกัดมาก
- Hubris ประกอบด้วยโปรแกรมจำนวนมากที่คอมไพล์แยกจากกันและเรียกว่า task ทำให้มีความต้องการทรัพยากรสูงกว่าระบบปฏิบัติการอื่นเล็กน้อย
- Matt Keeter เพื่อนร่วมงานเพิ่งทำให้ระบบฉลาดขึ้น โดยพยายามแพ็ก task ให้แน่นที่สุดเท่าที่จะทำได้ด้วยการใช้หลายพื้นที่ขนาดกำลังสอง
-
หลักฐานชิ้นสำคัญ
- Arjen ใช้ดีบักเกอร์ของ Hubris ที่ชื่อ Humility เพื่อตรวจสอบสวิตช์เครือข่ายที่ล้มเหลว
- เขาใช้คำสั่ง
humility tasksเพื่อพิมพ์รายการ task ที่กำลังรันอยู่บนโปรเซสเซอร์พร้อมข้อมูลสถานะ - และพบว่า task ที่รับผิดชอบลำดับการจ่ายไฟถูกรีสตาร์ตไปแล้ว 115 ครั้งเนื่องจาก memory fault
-
ขยายการยืมแบบ Rust ไปข้าม task ใน Hubris IPC
- task ของ Hubris สามารถส่งข้อความหากันผ่าน IPC ได้
- ข้อความเหล่านี้มีลักษณะและการทำงานคล้ายกับการเรียกฟังก์ชันมาก
- เมื่อ task หนึ่งยืมหน่วยความจำให้กับอีก task ก็ไม่ควรพยายามยืมหน่วยความจำที่ตัวเองไม่ได้เป็นเจ้าของจริง
-
เมื่อฟีเจอร์หันกลับมาโจมตี
- ฟีเจอร์สองอย่างสามารถรวมกันจนกลายเป็นบั๊กได้
- การแพ็ก task ทำงานแบบฉวยโอกาสในระบบบิลด์
- หากขนาดของ task A เปลี่ยนไปเล็กน้อย ตำแหน่งขอบเขตของพื้นที่ MPU ของ task B ที่ไม่เกี่ยวข้องกันก็อาจเลื่อนไปได้
-
สายเรียกเข้าจากข้างใน!
- จำเป็นต้องเปลี่ยนอัลกอริทึมการป้องกันหน่วยความจำ
- ต้องยอมให้หน่วยความจำที่ถูกยืมข้ามขอบเขตของพื้นที่ MPU ได้
-
การล้มเหลวอย่างมีระบบด้วย Hubris
- มีหลายสิ่งที่ไม่ได้เกิดขึ้นเมื่อระบบล้มเหลว
- พวกเขาซ่อมสวิตช์เครือข่ายที่พังได้ภายใน 3 ชั่วโมง
- การแยกความเสียหาย การล้มเหลวไปสู่สถานะปลอดภัย หน่วยความจำที่ใช้ร่วมกันอย่างปลอดภัย การออกแบบร่วมกันระหว่างเคอร์เนลกับดีบักเกอร์ ความเรียบง่ายของการออกแบบและการใช้งาน และการบูรณาการกันอย่างใกล้ชิดแบบไม่ยึดลำดับชั้นของทีม ล้วนช่วยได้
ความเห็นของ GN⁺
- บทความนี้แสดงให้เห็นถึงความสำคัญของการออกแบบซอฟต์แวร์ที่แข็งแกร่ง แม้ในระบบที่ซับซ้อน ผ่านกระบวนการค้นหาและแก้ไขบั๊กที่เกิดขึ้นในระบบปฏิบัติการชื่อ Hubris
- กระบวนการค้นหาและแก้บั๊กเน้นย้ำถึงความสำคัญของการทำงานเป็นทีมและเครื่องมือดีบักที่มีประสิทธิภาพในการแก้ปัญหาทางวิศวกรรมซอฟต์แวร์ที่ซับซ้อน
- มันยังแสดงให้เห็นว่าฟังก์ชันด้านการแยกส่วนของระบบและการจัดการความขัดข้องมีความสำคัญเพียงใดเมื่อใช้งานระบบอย่าง Hubris ซึ่งช่วยยกระดับเสถียรภาพและความสามารถในการบำรุงรักษาของระบบได้มาก
- บทความนี้ยังแสดงให้เห็นวิธีใช้ภาษาโปรแกรมที่ปลอดภัยอย่าง Rust เพื่อรับประกันความปลอดภัยของหน่วยความจำและลดบั๊กให้เหลือน้อยที่สุด ในระบบที่ใช้ Rust บั๊กประเภทนี้เกิดขึ้นได้ไม่บ่อย ซึ่งเป็นหลักฐานว่าการรับประกันด้าน memory safety ของ Rust มีประสิทธิภาพเพียงใดในทางปฏิบัติ
- โครงการหรือผลิตภัณฑ์อื่นที่มีลักษณะคล้ายกัน ได้แก่ seL4, FreeRTOS และ Zephyr ซึ่งล้วนเป็นระบบปฏิบัติการสำหรับระบบฝังตัวที่มีเป้าหมายและคุณลักษณะแตกต่างกัน
- เมื่อนำระบบอย่าง Hubris มาใช้ ควรพิจารณาปัจจัยต่าง ๆ เช่น ข้อจำกัดด้านหน่วยความจำ การจัดการ task และการออกแบบกลไก IPC ข้อดีของการเลือกระบบลักษณะนี้คือการออกแบบระบบที่แข็งแกร่งและการจัดการหน่วยความจำอย่างปลอดภัย ส่วนข้อเสียอาจเป็นความซับซ้อนของระบบและเส้นโค้งการเรียนรู้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
รีวิวโค้ดเคอร์เนล Hubris
ชื่นชมประกาศรับสมัครงาน
รีวิวโค้ดและข้อเสนอแนะ
TaskDesc::regionsประเมินกระบวนการดีบัก
ความสนใจต่อวัฒนธรรมของทีม Oxide
ลิงก์ข้อมูลที่เกี่ยวข้อง
เห็นด้วยกับปัญหาที่เกิดขึ้นระหว่างการดีบัก
ข้อเสนอเกี่ยวกับการจัดการฮาร์ดแวร์
ชื่นชมงานของ Oxide
ปฏิกิริยาต่อชื่อระบบปฏิบัติการ