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

Clang vs. Clang: อย่าทำให้ Clang โกรธ

  • เป็นบทความบล็อกที่ว่าด้วยการทดลองเกี่ยวกับ Clang
  • เมื่อลองดูการเปลี่ยนแปลงล่าสุดของ LLVM และ GCC ที่เกี่ยวข้องกับการปรับแต่งคอมไพเลอร์ จะพบว่ามีทั้งการปรับแต่ง การทดสอบการปรับแต่ง การแก้ไขการทดสอบ และการแก้บั๊ก
  • ผู้เขียนคอมไพเลอร์มักไม่อยากรับผิดชอบต่อบั๊กที่ตนเองเป็นผู้ใส่เข้าไป
  • การปรับแต่งคอมไพเลอร์แทบไม่ได้ช่วยเพิ่มประสิทธิภาพจริงมากนัก

ปัญหาของการปรับแต่งคอมไพเลอร์

  • คอมไพเลอร์ที่เปิดการปรับแต่งแล้วมีไม่บ่อยนักที่จะช่วยเพิ่มประสิทธิภาพได้จริง
  • ตัวอย่างเช่น อิมพลีเมนเทชัน avx2 ของ kyber768 เร็วกว่าซอร์สที่คอมไพล์ด้วยคอมไพเลอร์แบบปรับแต่งแล้วถึง 4 เท่า
  • ตามกฎของ Todd A. Proebsting การปรับแต่งคอมไพเลอร์แทบไม่มีส่วนช่วยต่อสมรรถนะการประมวลผล
  • ผลเบนช์มาร์กของ Arseny Kapoulkine ก็สรุปไปในทิศทางเดียวกัน

ปัญหาด้านความปลอดภัย

  • คอมไพเลอร์ที่ผ่านการปรับแต่งอาจก่อปัญหาด้านความปลอดภัย เช่น timing leak นอกเหนือจากบั๊กแบบดั้งเดิม
  • ตามงานวิจัย EuroS&P ปี 2018 การอัปเกรดคอมไพเลอร์อาจเปิด timing channel ทำให้โค้ดที่ปลอดภัยอยู่แล้วกลายเป็นมีช่องโหว่ได้
  • มีรายงานการโจมตีแบบจับเวลาได้สำเร็จกับโค้ดอ้างอิงของ Kyber ที่คอมไพล์ด้วยตัวเลือกการปรับแต่งของ Clang 15 ขึ้นไป

เครื่องมือ TIMECOP

  • TIMECOP 2 ฝังอยู่ในเฟรมเวิร์กทดสอบคริปโต SUPERCOP และสแกนหา conditional branch ที่มาจากความลับโดยอัตโนมัติ
  • ความต่างระหว่าง TIMECOP 1 กับ TIMECOP 2 คือ TIMECOP 2 จะทำเครื่องหมายเอาต์พุต RNG เป็นความลับโดยอัตโนมัติ และรันบนหลายคอร์

การเขียนโค้ดแบบคงเวลา

  • มีการบรรยายเกี่ยวกับวิธีเขียนโค้ดแบบคงเวลาในเดือนกรกฎาคม 2024
  • อธิบายฟังก์ชันแบบคงเวลาที่มีให้ใน libmceliece และ SUPERCOP
  • ตัวอย่างเช่น ฟังก์ชัน crypto_uint32_bitmod_mask(x,j) ทำให้คอมไพเลอร์ไม่สามารถมองออกว่าผลลัพธ์เป็นเพียง 1 บิต

การป้องกันปัญหาจากการปรับแต่งคอมไพเลอร์

  • วิธีหนึ่งในการป้องกันไม่ให้คอมไพเลอร์ใส่ timing leak เข้ามา คือแจกจ่ายไลบรารีในรูปแบบภาษาแอสเซมบลี
  • อย่างไรก็ตาม ภาษาแอสเซมบลีอาจทำให้การตรวจสอบความถูกต้องของซอฟต์แวร์ทำได้ยากขึ้น
  • กำลังมองหาวิธีใส่โค้ดป้องกัน timing leak เข้าไปในโค้ด C, C++ และภาษาอื่น ๆ ได้อย่างรวดเร็ว

แพตช์ clang-vs-clang

  • มีการเขียนแพตช์ให้กับเครื่องมือปรับแต่งของ LLVM เพื่อสแกนหา &1 และ >>31 พร้อมแสดงข้อความเตือน
  • ตัวอย่างเช่น ในโค้ด x >>= 31 จะมีการแสดงข้อความเตือน

บทสรุป

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

สรุปโดย GN⁺

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

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

 
GN⁺ 2024-08-05
ความเห็นจาก Hacker News
  • ผู้เขียนคอมไพเลอร์ไม่รับผิดชอบต่อบั๊กที่เกิดจากการปรับแต่งประสิทธิภาพ

    • ตามมาตรฐานภาษา บั๊กลักษณะนี้ถือเป็นความผิดของโปรแกรมเมอร์
    • นี่เป็นหลักฐานว่ามันไม่ใช่บั๊ก
  • เห็นด้วยกับความเห็นของ Bernstein แต่บางครั้งก็พาไปผิดทาง

    • ประโยชน์ของการปรับแต่งประสิทธิภาพแตกต่างกันไปตามกรณีการใช้งาน
    • มีข้อไม่พอใจว่าคอมไพเลอร์ C ไม่คำนึงถึงความหมายที่ไม่สามารถแสดงออกได้ในภาษา
    • สรุปได้ว่า "ให้ใช้ภาษาที่สามารถแสดงความหมายที่ต้องการได้"
  • C และ C++ ไม่เหมาะกับการเขียนอัลกอริทึมที่ต้องการการรับประกันเวลาแบบคงที่

    • มาตรฐานแทบไม่มีแนวคิดเรื่องเรียลไทม์
    • การตำหนินักพัฒนาคอมไพเลอร์เป็นการมุ่งไปผิดจุด
  • บน Intel CPU นั้น clang หรืออย่างอื่นใดก็ไม่สามารถสร้างโค้ดที่ถูกต้องได้ใน user mode

    • ไม่สามารถตั้งค่า DOITM ได้
  • ไม่เห็นด้วยกับข้ออ้างที่ว่าผู้เขียนคอมไพเลอร์ไม่รับผิดชอบต่อบั๊ก

    • นี่เป็นความเข้าใจผิดพื้นฐานเกี่ยวกับ "undefined behavior" ของ C
  • clang มีแอตทริบิวต์ clang::optnone ที่ใช้ปิดการปรับแต่งประสิทธิภาพเป็นรายฟังก์ชันได้

    • GCC มีแอตทริบิวต์ gnu::optimize สำหรับตั้งค่าระดับการปรับแต่งประสิทธิภาพ
    • clang::no_builtins จะปิดการปรับแต่ง memcpy และ memset
  • C มี undefined behavior มาก จนอาจทำให้ย้ายไปใช้ภาษาอื่น

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

    • อาจจำเป็นต้องมีคอมไพเลอร์เฉพาะทาง
  • เป็นความจริงที่ว่าบางภาษาและคอมไพเลอร์ไม่เหมาะกับการเขียนรูทีนคริปโตกราฟีแบบเวลาคงที่

    • แต่การสรุปว่าคอมไพเลอร์ทั้งหมดและภาษา non-assembly นั้นแย่ เป็นข้อสรุปที่ผิด
    • ควรเขียนคอมไพเลอร์และภาษาที่เฉพาะทางอย่างเรียบง่ายขึ้นมา
  • ในตัวอย่างฟังก์ชันหนึ่ง หากป้อนค่า SIZE_T_MAX จะเกิด undefined behavior

    • มีบั๊กลักษณะนี้อยู่มาก แต่ในทางปฏิบัติแล้วไม่สำคัญ