โปรแกรม TRACTOR ( Translating All C to Rust ) ที่ทะเยอทะยานของ DARPA ได้จุดประกายการอภิปรายอย่างเข้มข้นในชุมชนโปรแกรมเมอร์เกี่ยวกับเส้นทางที่ดีที่สุดสำหรับการรักษาความปลอดภัยของโค้ดเก่า ในขณะที่โปรแกรมมีเป้าหมายใช้โมเดลภาษาขนาดใหญ่เพื่อแปลงโค้ด C ที่มีช่องโหว่เป็น Rust ที่ปลอดภัยต่อหน่วยความจำโดยอัตโนมัติ นักพัฒนากำลังตั้งคำถามว่าแนวทางนี้แก้ไขความท้าทายที่แท้จริงหรือไม่ หรือทางเลือกอื่น ๆ อาจจะปпрактичнее กว่า
ภาพรวมโปรแกรม DARPA TRACTOR
- ชื่อเต็ม: Translating All C to Rust (TRACTOR)
- เป้าหมาย: ทำให้การแปลงโค้ด C เก่าไปเป็น Rust ที่ปลอดภัยต่อหน่วยความจำเป็นแบบอัตโนมัติ
- แนวทาง: รวมโมเดลภาษาขนาดใหญ่เข้ากับการตรวจสอบเชิงรูปแบบ
- เป้าหมาย: กำจัดช่องโหว่ด้านความปลอดภัยของหน่วยความจำในโปรแกรม C
- สถานะรางวัล: สัญญาเดียวที่มอบให้กับกลุ่มมหาวิทยาลัยที่ใช้แนวทาง "ForCLift"
ความท้าทายในการแปลงเกินกว่าการแปลงแบบธรรมดา
ชุมชนได้ยกความกังวลที่สำคัญเกี่ยวกับความซับซ้อนของการแปลง C เป็น Rust อย่างมีความหมาย ซึ่งแตกต่างจากเครื่องมือ transpilation พื้นฐานอย่าง C2Rust ที่สร้างโค้ด Rust ที่ไม่ปลอดภัยและมีช่องโหว่เดียวกันกับ C ต้นฉบับ TRACTOR มีเป้าหมายสร้าง Rust ที่ปลอดภัยและเป็นแบบฉบับอย่างแท้จริง สิ่งนี้ต้องการการวิเคราะห์ที่ซับซ้อนเพื่อเข้าใจเจตนาของโปรแกรมเมอร์ - การกำหนดว่า pointer แสดงถึงค่าเดียวหรืออาร์เรย์ การระบุรูปแบบความเป็นเจ้าของ และการจดจำสำนวน C ทั่วไปที่สามารถแปลเป็น Rust ที่เทียบเท่าได้อย่างปลอดภัย
อุปสรรคทางเทคนิคนั้นมีมาก การแปลงฟังก์ชัน C ที่รับ raw pointer และพารามิเตอร์ขนาดให้เป็น Rust slice ที่ปลอดภัยต้องการความเข้าใจความสัมพันธ์ระหว่างพารามิเตอร์เหล่านี้ทั่วทั้ง codebase สิ่งนี้เกี่ยวข้องกับทั้งการจดจำรูปแบบจากโมเดลภาษาขนาดใหญ่และการตรวจสอบอย่างเป็นทางการเพื่อให้แน่ใจว่าการแปลงรักษาความหมายของโปรแกรมในขณะที่ได้รับการรับประกันความปลอดภัย
ความท้าทายทางเทคนิคที่สำคัญ
- การวิเคราะห์ Pointer: การกำหนดว่า pointer แทนค่าเดียวหรือ array
- การแปลง Ownership: การแปลงการจัดการหน่วยความจำของ C ไปเป็นโมเดล ownership ของ Rust
- การจดจำ Idiom: การระบุและแปลงรูปแบบ C ทั่วไปไปเป็น Rust ที่ปลอดภัยและเทียบเท่า
- โครงสร้างข้อมูลแบบวงจร: การจัดการกราฟออบเจ็กต์ที่ซับซ้อนซึ่งไม่เข้ากับโมเดล ownership ของ Rust
- การรักษาประสิทธิภาพ: การรักษาประสิทธิภาพในขณะที่เพิ่มการรับประกันความปลอดภัย
แนวทางทางเลือกท้าทายกลยุทธ์ที่ยึด Rust เป็นหลัก
ส่วนสำคัญของการอภิปรายมุ่งเน้นไปที่ทางเลือกอื่น ๆ ที่ไม่ต้องการการย้ายภาษาแบบสมบูรณ์ โปรเจกต์อย่าง Fil-C แสดงให้เห็นว่า C สามารถทำให้ปลอดภัยต่อหน่วยความจำได้ผ่าน runtime instrumentation และ garbage collection ซึ่งอาจเสนอเส้นทางที่เข้ากันได้มากกว่าสำหรับระบบเก่า แนวทางนี้รักษาไวยากรณ์และความหมายที่คุ้นเคยของ C ในขณะที่เพิ่มการตรวจสอบความปลอดภัยอย่างครอบคลุม
ข้อโต้แย้งสำหรับการใช้ Rust แทนการใช้งาน C ที่ปลอดภัยต่อหน่วยความจำล้วนเกี่ยวกับประสิทธิภาพ และนั่นไม่ใช่ข้อโต้แย้งที่แย่! แต่เราควรซื่อสัตย์เกี่ยวกับเรื่องนี้
อย่างไรก็ตาม นักวิจารณ์ชี้ให้เห็นว่าทางเลือกดังกล่าวมาพร้อมกับ overhead ด้านประสิทธิภาพและอาจไม่เหมาะสมสำหรับแอปพลิเคชันทั้งหมด โดยเฉพาะอย่างยิ่งที่ต้องการการรับประกัน real-time หรือทำงานในสภาพแวดล้อมที่มีทรัพยากรจำกัดซึ่ง garbage collection ไม่เป็นไปได้
ทางเลือกด้านความปลอดภัยอื่นๆ ที่ได้หารือกัน
- Fil-C: การใช้งาน C ที่ปลอดภัยต่อหน่วยความจำพร้อมกับ garbage collection และการตรวจสอบ runtime
- C2Rust: เครื่องมือที่มีอยู่แล้วซึ่งสร้าง unsafe Rust ที่มีช่องโหว่เดียวกับ C ต้นฉบับ
- SaferCPlusPlus: ชุดย่อยของ C++ ที่ปลอดภัยต่อหน่วยความจำพร้อมการบังคับใช้แบบ static
- Enhanced C tooling: การปรับปรุง static analysis และ runtime instrumentation
ความแตกต่างในปรัชญาการออกแบบพื้นฐาน
การถกเถียงเผยให้เห็นความแตกต่างทางปรัชญาที่ลึกซึ้งกว่าเกี่ยวกับการออกแบบภาษาโปรแกรม นักพัฒนาบางคนโต้แย้งว่าโมเดลความปลอดภัยของ Rust แม้จะมีพลัง แต่ทำให้รูปแบบการเขียนโปรแกรมบางอย่างยากหรือไม่สามารถแสดงออกได้อย่างปลอดภัยโดยไม่จำเป็น โครงสร้างข้อมูลที่ซับซ้อนที่มี cycle ประเภทหนึ่งของ interior mutability และรูปแบบการเขียนโปรแกรมระบบระดับต่ำบางอย่างต้องการโค้ดที่ไม่ปลอดภัยหรือการเปลี่ยนแปลงสถาปัตยกรรมที่สำคัญใน Rust
ข้อจำกัดเหล่านี้ไม่จำเป็นต้องเป็นข้อบกพร่อง - มันสะท้อนปรัชญาการออกแบบของ Rust ในการป้องกันคลาสทั้งหมดของบั๊กผ่านการตรวจสอบ compile-time อย่างไรก็ตาม สิ่งนี้หมายความว่าการแปลโดยตรงจาก C เป็น Rust ที่ปลอดภัยอาจต้องการการปรับโครงสร้างโค้ดอย่างมากแทนที่จะเป็นการแปลงไวยากรณ์แบบง่าย ๆ
ความกังวลในการใช้งานจริง
นอกเหนือจากความท้าทายทางเทคนิค ชุมชนได้เน้นความกังวลเชิงปฏิบัติเกี่ยวกับการนำมาใช้ในระดับใหญ่ องค์กรหลายแห่งมี codebase C ที่กว้างขวางซึ่งรวมเข้ากับระบบ build ที่ซับซ้อน deployment pipeline และ toolchain ที่มีอยู่ ต้นทุนการเปลี่ยนแปลงและโอกาสในการนำบั๊กใหม่เข้ามาระหว่างการแปลงอาจมีน้อมหนักกว่าประโยชน์ด้านความปลอดภัยสำหรับแอปพลิเคชันบางอย่าง
การอภิปรายยังสัมผัสกับความเชี่ยวชาญของนักพัฒนาและความท้าทายในการจ้างงาน ในขณะที่ Rust เสนอการรับประกันความปลอดภัยที่น่าสนใจ กลุ่มนักพัฒนา C ที่มีอยู่มีจำนวนมากกว่าผู้เชี่ยวชาญ Rust อย่างมาก ทำให้การบำรุงรักษาและการพัฒนาต่อไปของโค้ดที่แปลแล้วอาจเป็นปัญหาสำหรับองค์กรหลายแห่ง
มองไปข้างหน้า
แม้จะมีความท้าทาย การลงทุนของ DARPA ในการวิจัยการแปลงอัตโนมัติแสดงถึงขั้นตอนสำคัญในการแก้ไขหนี้ความปลอดภัยขนาดใหญ่ในโค้ด C เก่า การรวมกันของเทคนิค machine learning และ formal verification ของโปรแกรมอาจสร้างแนวทางที่ก้าวล้ำซึ่งทำให้การย้ายโค้ดในระดับใหญ่เป็นไปได้มากกว่าวิธีการด้วยมือในปัจจุบัน
ไม่ว่า TRACTOR จะประสบความสำเร็จในเป้าหมายที่ทะเยอทะยานหรือแนวทางทางเลือกอย่างการปรับปรุงเครื่องมือ C และระบบความปลอดภัย runtime จะพิสูจน์ว่าปฏิบัติได้มากกว่า ความคิดริเริ่มนี้ได้จุดประกายการอภิปรายที่มีค่าเกี่ยวกับอนาคตของการเขียนโปรแกรมระบบและความปลอดภัยซอฟต์แวร์แล้ว ทางออกที่ดีที่สุดอาจเกี่ยวข้องกับการรวมแนวทางต่าง ๆ ที่ปรับให้เหมาะกับกรณีการใช้งานและความต้องการขององค์กรที่แตกต่างกัน
อ้างอิง: Eliminating Memory Safety Vulnerabilities Once and For All