Clang เสนอโหมดเสริมความแข็งแกร่งเพื่อเพิ่มความปลอดภัยให้ C/C++ แต่ชุมชนถกเถียงเรื่องการเปลี่ยนแปลงที่อาจทำลายโค้ดเดิม

ทีมชุมชน BigGo
Clang เสนอโหมดเสริมความแข็งแกร่งเพื่อเพิ่มความปลอดภัยให้ C/C++ แต่ชุมชนถกเถียงเรื่องการเปลี่ยนแปลงที่อาจทำลายโค้ดเดิม

ทีมคอมไพเลอร์ 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++ วิวัฒนาการเพื่อตอบสนองต่อความต้องการด้านความปลอดภัยที่เพิ่มขึ้น และอาจกำหนดมาตรฐานใหม่สำหรับการเสริมความแข็งแกร่งของโปรแกรมด้วยความช่วยเหลือของคอมไพเลอร์ทั่วทั้งระบบนิเวศ

อ้างอิง: [RFC] Hardening mode for the compiler