ทีมคอมไพเลอร์ Clang ได้เปิดเผยข้อเสนอที่ทะเยอทะยานสำหรับโหมดเสริมความแข็งแกร่งใหม่ที่ออกแบบมาเพื่อปรับปรุงความปลอดภัยและความมั่นคงในโปรแกรม C และ C++ ความคิดริเริ่มนี้มีเป้าหมายที่จะรวมกลไกความปลอดภัยที่กระจัดกระจายอยู่เข้าเป็นฟีเจอร์เดียวที่ใช้งานง่าย ซึ่งสามารถเปิดใช้งานมาตรการป้องกันต่างๆ เช่น การตรวจสอบขอบเขต การป้องกันสแต็ก และการวินิจฉัยที่ปรับปรุงแล้วได้อย่างอัตโนมัติ
ข้อเสนอนี้เกิดขึ้นในช่วงเวลาที่ความกังวลเรื่องความปลอดภัยใน C และ C++ ได้ถึงจุดเปลี่ยนแล้ว โดยหน่วยงานรัฐบาลและผู้นำอุตสาหกรรมกำลังผลักดันให้มีแนวทางการเขียนโปรแกรมที่ปลอดภัยมากขึ้น แม้ว่า Clang จะมีฟีเจอร์ความปลอดภัยมากมายอยู่แล้ว แต่ปัจจุบันฟีเจอร์เหล่านั้นกระจัดกระจายอยู่ในแฟล็ก แมโคร และการตั้งค่าต่างๆ ที่นักพัฒนาหลายคนพบว่ายากต่อการใช้งาน
คุณสมบัติที่เสนอสำหรับโหมดเสริมความปลอดภัย:
- แฟล็กเตือน:
-Wall
,-Wextra
,-Wshadow
,-Wunused
- ตัวเลือก Sanitizer:
-fsanitize=address
,-fstack-protector-strong
- แมโคร Security:
__FORTIFY_SOURCE
,_GLIBCXX_ASSERTIONS
- การป้องกันระดับเครื่อง: retpoline, LVI/LFence
- มาตรการรักษาความปลอดภัยตัวระบุ Unicode
- การระบุมาตรฐานภาษาแบบบังคับ
ชุมชนถกเถียงเรื่องการแลกเปลี่ยนระหว่างประสิทธิภาพกับความปลอดภัย
การอภิปรายนี้ได้จุดประกายความสนใจอย่างมากเกี่ยวกับผลกระทบต่อประสิทธิภาพของมาตรการเสริมความแข็งแกร่งดังกล่าว การพัฒนาล่าสุดในการตรวจสอบขอบเขตแสดงผลลัพธ์ที่น่าสนใจ โดยการใช้งานบางแบบสามารถทำให้โอเวอร์เฮดต่ำถึง 0.3% สำหรับการตรวจสอบขอบเขตของไลบรารีมาตรฐาน นี่คือการปรับปรุงที่สำคัญจากสมมติฐานก่อนหน้านี้ที่ว่าการป้องกันดังกล่าวจะมีค่าใช้จ่ายสูงเกินไปสำหรับการใช้งานจริง
อย่างไรก็ตาม ชุมชนยังคงแบ่งแยกกันเรื่องแนวทางการใช้งาน นักพัฒนาบางคนชี้ไปที่โซลูชันที่มีอยู่แล้วเช่น Valgrind สำหรับการตรวจจับข้อผิดพลาดของหน่วยความจำ แม้ว่าเครื่องมือเหล่านี้จะมาพร้อมกับการลดประสิทธิภาพอย่างมาก ซึ่งมักจะเพิ่มเวลาการทำงานขึ้น 10 ถึง 30 เท่า โหมดเสริมความแข็งแกร่งที่เสนอนี้มีเป้าหมายที่จะให้ทางเลือกกลางที่มีการป้องกันที่มีความหมายด้วยต้นทุนประสิทธิภาพที่ยอมรับได้
เกณฑ์มาตรฐานประสิทธิภาพ:
- ค่าใช้จ่ายเพิ่มเติมจากการตรวจสอบขอบเขต: ต่ำสุดเพียง 0.3% สำหรับการดำเนินงานของไลบรารีมาตรฐาน
- การตรวจสอบหน่วยความจำด้วย Valgrind : เพิ่มเวลาการทำงาน 10-30 เท่า
- การตรวจสอบขอบเขตในโหมดดีบัก: พร้อมใช้งานแล้วใน MSVC และ Clang พร้อม Microsoft STL
การเปลี่ยนแปลงที่ทำลายโค้ดเดิมก่อให้เกิดการถกเถียง
บางทีแง่มุมที่ถกเถียงกันมากที่สุดของข้อเสนอนี้คือจุดยืนของทีมเกี่ยวกับความเข้ากันได้แบบย้อนหลัง RFC ระบุอย่างชัดเจนว่าการที่โค้ดเสียหายระหว่างการปล่อยคอมไพเลอร์จะเป็นฟีเจอร์ ไม่ใช่บั๊กในโหมดเสริมความแข็งแกร่ง แนวทางนี้ได้สร้างการถกเถียงอย่างร้อนแรงภายในชุมชน
โค้ดที่ทำงานได้อยู่แล้วก็คือโค้ดที่ทำงานได้อยู่แล้ว ฉันไม่สนใจว่ามันจะดูน่าสงสัยต่อฟีเจอร์คอมไพเลอร์แปลกๆ ของใครบางคน
ความรู้สึกนี้สะท้อนความกังวลที่กว้างขึ้นเกี่ยวกับการเน้นย้ำแบบดั้งเดิมของชุมชน C++ เรื่องความเข้ากันได้แบบย้อนหลัง ผู้ดูแลแพ็กเกจและผู้ใช้องค์กรหลายคนกังวลเกี่ยวกับผลกระทบในทางปฏิบัติของแนวทางดังกล่าว โดยกลัวว่าอาจสร้างภาระในการบำรุงรักษาและบังคับให้องค์กรต้องดูแลคอมไพเลอร์หลายเวอร์ชัน
ตัวเลือกการใช้งานที่อยู่ระหว่างการพิจารณา
ทีม Clang ได้ร่างแนวทางที่เป็นไปได้หลายแบบสำหรับการใช้งานโหมดเสริมความแข็งแกร่ง ตั้งแต่ไฟล์การกำหนดค่าที่สามารถส่งมาพร้อมกับคอมไพเลอร์ ไปจนถึงโหมดไดรเวอร์ใหม่ แฟล็กมุมฉากสำหรับแง่มุมความปลอดภัยต่างๆ หรือแฟล็กครอบคลุมเดียว แต่ละแนวทางนำเสนอการแลกเปลี่ยนที่แตกต่างกันในแง่ของการใช้งาน ความยืดหยุ่น และการรวมเข้ากับระบบบิลด์ที่มีอยู่
ข้อเสนอยังกล่าวถึงความเข้ากันได้กับโหมด -fhardened
ที่มีอยู่ของ GCC ในขณะที่เน้นย้ำว่าการใช้งานของ Clang อาจแตกต่างกันในพฤติกรรมเฉพาะ แนวทางที่เป็นจริงนี้ยอมรับว่าความเข้ากันได้ที่สมบูรณ์แบบระหว่างคอมไพเลอร์มักจะไม่สามารถทำได้ในทางปฏิบัติ ในขณะที่ยังคงทำงานไปสู่เป้าหมายความปลอดภัยร่วมกัน
แนวทางการใช้งานที่อยู่ระหว่างการพิจารณา:
- ไฟล์ Config: ส่งมอบการกำหนดค่าการเสริมความแข็งแกร่งพร้อมกับ Clang เปิดใช้งานผ่าน
-config=hardened
- โหมด Driver: สร้างตัวขับเคลื่อนคอมไพเลอร์แบบ "hardened" แยกต่างหาก
- แฟล็กแบบตั้งฉาก: แฟล็กแยกต่างหากสำหรับตัวเลือกภาษา การวินิจฉัย และ sanitizer
- แฟล็กเดียว: แฟล็กแบบรวม (เช่น
-fhardened
) ที่ควบคุมทุกด้านของการเสริมความแข็งแกร่ง
ฟีเจอร์ความปลอดภัยนอกเหนือจากการตรวจสอบขอบเขต
โหมดเสริมความแข็งแกร่งจะครอบคลุมมากกว่าแค่ความปลอดภัยของหน่วยความจำ ข้อเสนอรวมถึงบทบัญญัติสำหรับการจัดการช่องโหว่ตัวระบุ Unicode ที่เปิดใช้งานการโจมตี homoglyph ซึ่งอักขระที่ดูคล้ายกันสามารถใช้เพื่อสร้างโค้ดที่หลอกลวงได้ การโจมตีดังกล่าวใช้ประโยชน์จากอักขระ Unicode ที่ดูเหมือนกับตัวอักษร ASCII แต่มีความหมายที่แตกต่างกันต่อคอมไพเลอร์
นอกจากนี้ โหมดนี้ยังสามารถเปิดใช้งานแฟล็กคำเตือนต่างๆ sanitizer กลไกการป้องกันสแต็ก และแมโครที่เน้นความปลอดภัยเช่น __FORTIFY_SOURCE
และ _GLIBCXX_ASSERTIONS
แนวทางที่ครอบคลุมนี้มีเป้าหมายที่จะสร้างสภาพแวดล้อมการพัฒนาที่ให้ความสำคัญกับความปลอดภัยเป็นอันดับแรก โดยไม่ต้องให้นักพัฒนากำหนดค่าการตั้งค่าแต่ละรายการหลายสิบรายการด้วยตนเอง
มองไปข้างหน้า
ทีม Clang กำลังแสวงหาความคิดเห็นจากชุมชนเกี่ยวกับทิศทางระดับสูงก่อนดำเนินการต่อด้วยแผนการใช้งานที่มีรายละเอียด ความสำเร็จของความคิดริเริ่มนี้อาจมีอิทธิพลอย่างมากต่อวิธีที่การพัฒนา C และ C++ วิวัฒนาการเพื่อตอบสนองต่อความต้องการด้านความปลอดภัยที่เพิ่มขึ้น และอาจกำหนดมาตรฐานใหม่สำหรับการเสริมความแข็งแกร่งของโปรแกรมด้วยความช่วยเหลือของคอมไพเลอร์ทั่วทั้งระบบนิเวศ