1 คะแนน โดย GN⁺ 2024-04-28 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

ภาพรวมของ Hubris IPC

  • Hubris ใช้เคอร์เนลขนาดเล็กที่ไม่ขึ้นกับแอปพลิเคชัน และโค้ดส่วนใหญ่ (ไดรเวอร์, ลอจิกแอปพลิเคชัน, เน็ตเวิร์กสแตก ฯลฯ) อยู่ในทาสก์แยกที่ถูกคอมไพล์แยกและแยกการทำงานออกจากกัน
  • ทาสก์เหล่านี้สามารถสื่อสารกันได้โดยใช้ระบบส่งข้อความข้ามทาสก์ (IPC)
  • IPC ของ Hubris ประกอบด้วยปฏิบัติการหลัก 3 อย่างที่ติดตั้งในเคอร์เนล (RECV, SEND, REPLY)
    • RECV: รับข้อความขาเข้าที่มีลำดับความสำคัญสูงสุด หรือบล็อกจนกว่าจะมีข้อความมาถึง
    • SEND: ส่งข้อความและการควบคุมไปยังทาสก์ผู้รับ และหยุดผู้เรียกชั่วคราว ผู้เรียกจะเข้าสู่สถานะรอจนกว่าจะได้รับการตอบกลับ
    • REPLY: ส่งการตอบกลับให้ทาสก์ที่ก่อนหน้านี้ใช้ SEND เพื่อให้ทำงานต่อได้

โหมดความล้มเหลวใหม่ที่น่าสนใจ

  • เนื่องจาก IPC ข้ามขอบเขตของทาสก์ และทาสก์ของ Hubris เป็นโปรแกรมที่คอมไพล์แยกกัน จึงต้องระวังเมื่อจะตั้งสมมติฐานกับ IPC แบบเดียวกับที่คอมไพเลอร์ตั้งไว้ในการเรียกฟังก์ชัน
  • ทุกทาสก์ที่ทำหน้าที่เป็นเซิร์ฟเวอร์ IPC ใน Hubris ต้องรับมือกับข้อผิดพลาดที่อาจเกิดขึ้นดังต่อไปนี้:
    • ได้รับข้อความที่มีอินเทอร์เฟซและรหัสปฏิบัติการที่ไม่เหมาะสม
    • ได้รับชุดไบต์ที่ไม่สามารถตีความได้แทนชนิดข้อความที่คาดไว้ หรือได้รับข้อความที่สั้นหรือยาวเกินไป
    • ไม่ได้รับหน่วยความจำที่จำเป็น (เช่น หน่วยความจำที่เขียนได้)

ในโปรแกรมปกติและถูกต้อง สถานการณ์เหล่านี้จะไม่เกิดขึ้น

  • ในโปรแกรม Hubris ที่ปกติ สถานการณ์ที่กล่าวมาข้างต้นจะไม่เกิดขึ้น
  • ทาสก์เชื่อมโยงถึงกันด้วยการตั้งค่าของระบบบิลด์ จึงยากที่จะสับสนกัน
  • ไคลเอนต์และเซิร์ฟเวอร์ใช้โค้ด Rust ที่สร้างขึ้น ทำให้สามารถสมมติได้ว่าระบบชนิดข้อมูลทำงานข้ามขอบเขตของทาสก์

เคอร์เนลไม่ยอมให้มีเรื่องเหลวไหลใด ๆ ทั้งสิ้น

  • ใน Unix หากละเมิดเงื่อนไขเบื้องต้นของ system call ระบบจะส่งรหัสผิดพลาดกลับไปยังผู้เรียก แต่ใน Hubris ทาสก์จะถูกทำลายทันที
  • เคอร์เนลของ Hubris ส่งข้อผิดพลาดให้ทาสก์ที่ละเมิดกฎของเคอร์เนลผ่านแนวคิดที่เรียกว่า Synthetic Fault
  • ใน Hubris เมื่อเกิดข้อผิดพลาดจากฮาร์ดแวร์หรือ Synthetic Fault ทาสก์จะหยุดทันทีและกู้คืนไม่ได้

ฝั่งเซิร์ฟเวอร์ก็ไม่ยอมให้มีเรื่องเหลวไหลเช่นกัน

  • เซิร์ฟเวอร์สามารถส่งข้อผิดพลาดไปยังไคลเอนต์ได้ผ่าน system call ลำดับที่ 13 และแปลกที่สุดที่ชื่อ REPLY_FAULT
  • REPLY_FAULT คล้ายกับ REPLY แต่แทนที่จะส่งข้อความและทำให้ทาสก์กลับมารันได้ มันจะส่งข้อผิดพลาดและหยุดทาสก์นั้น
  • REPLY_FAULT ช่วยหลีกเลี่ยงการจัดการข้อผิดพลาด IPC ที่ไม่จำเป็น โปรแกรมปกติสามารถทำงานราวกับว่าไม่มีทางเกิดปัญหาได้ ส่วนโปรแกรมที่ผิดปกติจะไม่มีโอกาสแม้แต่จะจัดการข้อผิดพลาด
  • REPLY_FAULT ยังเปิดทางใหม่ในการกำหนดและทำข้อผิดพลาดเฉพาะแอปพลิเคชัน เช่น กฎควบคุมการเข้าถึง

ความเห็นของ GN⁺

  • REPLY_FAULT เป็นกลไกทรงพลังที่ทำให้เซิร์ฟเวอร์สามารถก่อให้เกิด panic! ข้ามโปรเซสในฝั่งไคลเอนต์ได้โดยไม่ต้องอาศัยความร่วมมือจากฝั่งไคลเอนต์ ทำให้ Hubris เป็นระบบที่เป็นปฏิปักษ์ต่อโปรแกรมไม่ประสงค์ดีอย่างมาก
  • ข้อเสียของ REPLY_FAULT คือทำให้การทดสอบแบบ fuzzing ยากมาก ทาสก์แนว chaos engineering ที่สร้าง IPC หรือ system call แบบสุ่มจะถูกรีเซ็ตแทบจะทันทีในเกือบทุกการทำงาน
  • อย่างไรก็ตาม เนื่องจากทาสก์ Hubris ปกติไม่ได้สร้างข้อความ IPC แบบไดนามิก จึงสามารถทำงานได้โดยไม่ต้องรับรู้เลยว่ามี REPLY_FAULT อยู่
  • ผ่าน REPLY_FAULT เซิร์ฟเวอร์สามารถก่อข้อผิดพลาดให้ไคลเอนต์แบบสุ่มได้ แต่การประเมินเรื่องนี้ยังไม่เสร็จสมบูรณ์
  • การจัดการข้อผิดพลาดแบบดุดันของ Hubris ช่วยให้พบข้อผิดพลาดได้ตั้งแต่ช่วงต้นของการพัฒนา และต่างจากรหัสผิดพลาดตรงที่ไม่สามารถเพิกเฉยต่อข้อผิดพลาดได้
  • หากใช้วิธีทั่วไปในการจัดการข้อผิดพลาด IPC อาจเกิดโอเวอร์เฮดที่ไม่จำเป็นแม้กับโปรแกรมปกติ REPLY_FAULT ดูจะเป็นทางออกที่งดงามซึ่งหลีกเลี่ยงสิ่งนี้ได้ พร้อมทั้งรับมือกับโปรแกรมผิดปกติอย่างเข้มงวด

1 ความคิดเห็น

 
GN⁺ 2024-04-28
ความคิดเห็นจาก Hacker News

สรุปได้ดังนี้:

  • มีการตั้งข้อกังวลว่า REPLY_FAULT จะแพร่กระจายเป็นลูกโซ่หรือไม่ และช่องโหว่ที่อาจเกิดจากสิ่งนั้น

    • ในสถานการณ์ที่ A รอ B และ B รอ C ต้องตรวจสอบว่าเมื่อ C ส่ง REPLY_FAULT แล้ว A จะถูกยุติไปด้วยหรือไม่
    • ถ้าเป็นเช่นนั้น ระบบทั้งหมดอาจเปราะบางได้
    • ถ้า SEND เป็นโครงสร้างแบบวนรอบ ก็อาจทำให้จบการทำงานของตัวเองโดยไม่ตั้งใจได้
  • REPLY_FAULT มอบวิธีสำหรับกำหนดและนำข้อผิดพลาดเฉพาะแอปพลิเคชัน เช่น การควบคุมการเข้าถึง ไปใช้งาน

    • สิ่งนี้มีประโยชน์เมื่อระบบมีขนาดเล็ก เชื่อมโยงกันแน่นแฟ้น และผู้ออกแบบระบบเป็นผู้เขียนแอปพลิเคชันเองเป็นส่วนใหญ่
    • แต่เมื่อทำงานร่วมกับโค้ดของบุคคลที่สาม ก็มีความกังวลว่าอีกฝ่ายจะทำให้โปรเซสถูกยุติทันทีได้ตลอดเวลา
    • ในโลกนี้มีไดรเวอร์และแบ็กกราวนด์โปรเซสคุณภาพแย่มากมายที่ถูกเขียนโดยนักพัฒนาซึ่งต้องทนทุกข์กับผู้ดูแลระบบ
  • ในระบบที่ทีมเดียวเป็นผู้เขียนโค้ดทั้งหมด การกำจัดไคลเอนต์ที่น่าสงสัยออกไปอาจช่วยเพิ่มความเร็วในการทำซ้ำพัฒนาได้

  • Hubris อาจมองได้ว่าเป็นเคอร์เนลที่ทำให้เซิร์ฟเวอร์สามารถทำเอฟเฟกต์ที่ไคลเอนต์จัดการเองไม่ได้

    • สิ่งนี้ทำให้การนำโค้ดกลับมาใช้ซ้ำและการประกอบรวมยากขึ้น แต่ทำให้โมเดลการทำงานเรียบง่ายขึ้น
    • ในระบบฝังตัวแบบคงที่ นี่อาจเป็นจุดแลกเปลี่ยนที่เหมาะสม
  • Hubris และ Humility เป็นเทคโนโลยีที่อยากทุ่มเทลงลึก แต่ติดข้อจำกัดด้านเวลาและภาระหน้าที่

  • มีการเสนอรหัสสถานะ HTTP 499 ใน RFC วันเมษาหน้าโง่ โดยมีความหมายว่า "คุณควรรู้สึกละอาย"

    • สิ่งนี้เข้ากับบริบทแบบ "อะไรเนี่ย... แต่จริง ๆ ก็ไม่เลวนะ"
  • มีการอ้างคำพูดของไอน์สไตน์ว่า "ทำให้เรียบง่ายที่สุดเท่าที่จะเป็นไปได้ แต่ไม่เรียบง่ายเกินไป" พร้อมชี้ว่าการออกแบบของ Hubris ละเมิดส่วนหลัง

    • ไม่มีความสนใจต่อสภาพแวดล้อมการทำงานที่ไม่ยอมรับความวุ่นวายในโลกจริงเลย
  • Humility เป็นชื่อที่ยอดเยี่ยมสำหรับดีบักเกอร์

    • โปรแกรมเมอร์จำนวนมากปฏิเสธการใช้ดีบักเกอร์ เพราะตั้งสมมติฐานว่าโค้ดที่ "ดี" ไม่จำเป็นต้องดีบัก
  • บน Linux แม้จะไม่สามารถทำให้โปรแกรมอื่นจบการทำงานโดยตรงได้ด้วยแค่ซ็อกเก็ต แต่ก็สามารถยุติโปรเซสอื่นหรือแม้แต่รีบูตได้หากมีสิทธิ์ root

    • ในคอนเทนเนอร์ การมีสิทธิ์ root เป็นเรื่องปกติ จึงมีความเสี่ยงลักษณะนี้อยู่
  • แนวคิดนี้ค่อนข้างขัดกับภูมิปัญญาเดิมของระบบเครือข่ายที่ว่า "รับเข้ามาอย่างผ่อนปรน และส่งออกไปอย่างเข้มงวด"

    • อย่างไรก็ตาม หากต้องการเปลี่ยน API พร้อมรักษาความเข้ากันได้กับโปรแกรมเดิม ก็เลี่ยงไม่ได้ที่จะต้องผ่อนปรนตอนรับเข้า