การใช้คอมไพเลอร์ C ที่ล้าสมัยนั้นมีความเสี่ยงด้านความปลอดภัยหรือไม่?


139

เรามีระบบสร้างในการผลิตที่ไม่มีใครใส่ใจและเครื่องจักรเหล่านี้ใช้ GCC รุ่นโบราณเช่น GCC 3 หรือ GCC 2

และฉันไม่สามารถโน้มน้าวฝ่ายบริหารให้อัปเกรดเป็นรุ่นล่าสุดได้: พวกเขาพูดว่า "หากยังไม่พังไม่ต้องแก้ไข"

เนื่องจากเรารักษาฐานรหัสเก่ามาก (เขียนในยุค 80) รหัส C89 นี้จึงรวบรวมได้ดีกับคอมไพเลอร์เหล่านี้

แต่ฉันไม่แน่ใจว่าควรใช้สิ่งเก่า ๆ เหล่านี้หรือไม่

คำถามของฉันคือ:

การใช้คอมไพเลอร์ C ตัวเก่าสามารถลดความปลอดภัยของโปรแกรมที่คอมไพล์ได้ไหม

UPDATE:

รหัสเดียวกันนี้สร้างขึ้นโดย Visual Studio 2008 สำหรับเป้าหมาย Windows และ MSVC ยังไม่รองรับ C99 หรือ C11 (ฉันไม่ทราบว่า MSVC รุ่นใหม่ทำ) และฉันสามารถสร้างมันบนกล่อง Linux โดยใช้ GCC ล่าสุด ดังนั้นหากเราเพิ่งจะลดลงใน GCC รุ่นใหม่มันอาจจะสร้างได้ดีเหมือนเดิม


5
คำถามที่น่าสนใจ - นี่อาจคุ้มค่าที่จะอ่านอย่างรวดเร็วเช่นกัน - developers.slashdot.org/story/13/10/29/2150211/ … .. ดังนั้นคอมไพเลอร์รุ่นใหม่อาจประนีประนอมความปลอดภัยเมื่อปรับให้เหมาะสม
Neil

6
gcc รุ่นเก่าเหล่านั้นรองรับการรวบรวมเป็น PIC / PIE สำหรับ ASLR หรือไม่ พวกเขาสนับสนุนหมู่เกาะคานารีหรือไม่? W ^ X (NX)? หากไม่มีการแก้ไขข้อบกพร่องสำหรับข้อบกพร่องนั้นเป็นเหตุผลที่ดีในการอัพเกรด
EOF

12
เพียงแค่ดูคำเตือนจาก gcc 4.x อาจเปิดเผยช่องโหว่ความปลอดภัยที่มีอยู่ทั้งหมดที่คุณไม่เคยรู้มาทันที
OrangeDog

7
@ OrangeDog: ทำไม gcc 4.x gcc6 เป็นซีรีย์เปิดตัวในปัจจุบันและ gcc 5 เปิดตัวมาระยะหนึ่งแล้ว แต่ใช่การแก้ไขปัญหาใด ๆ ที่ระบุโดย-O3 -Wall -Wextra -fsanitize=undefinedgcc และ clang ที่ทันสมัยควรช่วย
Peter Cordes

4
@OrangeDog GCC ได้ไปที่หมายเลขเวอร์ชันการตลาด GCC 5 สมควรได้รับการชนรุ่นใหญ่เนื่องจากพวกเขาเปลี่ยนมาตรฐาน C และ C ++ เริ่มต้นและ libstdc ++ ABI GCC 6 ควรเรียกว่า 5.1
zwol

คำตอบ:


102

ที่จริงฉันจะโต้แย้งตรงกันข้าม

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

รุ่นล่าสุดของ gcc (และเสียงดังกราว) เริ่มรักษากรณีเหล่านี้เนื่องจากโอกาสในการปรับให้เหมาะสมไม่สนใจหากพวกเขาเปลี่ยนวิธีการทำงานของไบนารีในสภาพ "พฤติกรรมที่ไม่ได้กำหนด" สิ่งนี้แย่มากถ้า codebase ของคุณถูกเขียนขึ้นโดยผู้ที่ปฏิบัติต่อ C เช่น "assembler แบบพกพา" เมื่อเวลาผ่านไปเครื่องมือเพิ่มประสิทธิภาพได้เริ่มดูโค้ดที่ใหญ่ขึ้นและใหญ่ขึ้นเมื่อทำการเพิ่มประสิทธิภาพเหล่านี้เพิ่มโอกาสให้ไบนารีจะจบลงด้วยการทำอย่างอื่นนอกจาก "สิ่งที่ไบนารีที่สร้างโดยคอมไพเลอร์ใบ้" จะทำอย่างไร

มีสวิตช์คอมไพเลอร์เพื่อเรียกคืนพฤติกรรม "ดั้งเดิม" (-fwrapv และ -fno-เคร่งครัด - aliasing สำหรับทั้งสองที่ฉันกล่าวถึงข้างต้น) แต่ก่อนอื่นคุณต้องรู้เกี่ยวกับพวกเขา

ในขณะที่ในหลักการข้อผิดพลาดของคอมไพเลอร์สามารถเปลี่ยนรหัสที่สอดคล้องกันเป็นช่องโหว่ความปลอดภัยฉันจะพิจารณาความเสี่ยงของสิ่งนี้ที่จะละเลยในรูปแบบที่ยิ่งใหญ่ของสิ่งต่าง ๆ


13
แต่ข้อโต้แย้งนี้ใช้ได้ทั้งสองทาง หากคอมไพเลอร์สามารถคาดการณ์ได้ว่า "พฤติกรรมที่ไม่ได้กำหนด" มันอาจจะง่ายกว่าที่จะใช้มันในทางที่เป็นอันตราย ...
André

18
@Andre รหัสที่รวบรวมมีพฤติกรรมที่ไม่ได้คาดการณ์ไว้แล้ว กล่าวคือเมื่อโค้ดถูกคอมไพล์แล้วพฤติกรรมที่คาดเดาไม่ได้ตอนนี้สามารถคาดเดาได้ในเวอร์ชั่นที่คอมไพล์นั้น
user253751

6
people who treated C like a "portable assembler"ไม่ใช่ว่า C คืออะไร?
Max

10
@ Max คำตอบนี้เตือนอย่างแม่นยำเกี่ยวกับความจริงที่ว่าแนวคิด "อุปกรณ์ประกอบแบบพกพา" นั้นล้าสมัยอย่างน้อยในทางปฏิบัติเนื่องจากเครื่องมือเพิ่มประสิทธิภาพที่ทันสมัย และฉันจะยืนยันว่ามันไม่เคยถูกต้องในแนวความคิดที่จะเริ่มต้นด้วย
Theodoros Chatzigiannakis

6
ไม่มีความเห็นอกเห็นใจที่นี่สำหรับผู้ที่พึ่งพาพฤติกรรมที่ไม่ได้กำหนดและต่อมาก็เริ่มเก็บเกี่ยวสิ่งที่พวกเขาหว่าน นี่ไม่ได้หมายความว่าคอมไพเลอร์ที่ใหม่กว่ามีความปลอดภัยน้อยกว่าโดยทั่วไป - นั่นหมายความว่าโค้ดที่ไม่สามารถปฏิบัติได้นั้นเป็นระเบิดเวลา ความผิดควรได้รับการจัดสรรตามความเหมาะสม
underscore_d

52

มีความเสี่ยงในการกระทำทั้งสอง


คอมไพเลอร์ที่เก่ากว่ามีข้อได้เปรียบของการกำหนดและสิ่งใดก็ตามที่แตกในนั้นอาจมี (แต่ไม่มีการรับประกัน) ที่ได้รับการแก้ไขเรียบร้อยแล้ว

ในกรณีนี้คอมไพเลอร์ใหม่เป็นแหล่งที่มาของข้อบกพร่องใหม่


ในอีกทางหนึ่งคอมไพเลอร์ใหม่มาพร้อมกับเครื่องมือเพิ่มเติม :

  • GCC และ Clang ทั้งสองตอนนี้มีsanitizersซึ่งสามารถใช้เป็นรันไทม์เพื่อตรวจจับพฤติกรรมที่ไม่ได้กำหนดของประเภทต่างๆ (Chandler Carruth ของทีม Google Compiler อ้างสิทธิ์เมื่อปีที่แล้วว่าเขาคาดหวังว่าจะครอบคลุมทั้งหมด)
  • เสียงดังกราวอย่างน้อยก็แข็งตัวอย่างเช่นControl Flow Integrityกำลังตรวจจับ hi-jacks ของโฟลว์การควบคุมนอกจากนี้ยังมีการชุบแข็งเพื่อป้องกันการโจมตีแบบกองซ้อน (โดยแยกส่วนการไหลของส่วนควบคุมของสแต็กจากส่วนข้อมูล) ; คุณสมบัติการชุบแข็งมักจะมีค่าใช้จ่ายต่ำ (ค่าใช้จ่ายของ CPU <1%)
  • Clang / LLVM ยังทำงานกับlibFuzzerซึ่งเป็นเครื่องมือในการสร้างการทดสอบหน่วย fuzzing แบบใช้เครื่องมือที่สำรวจพื้นที่อินพุตของฟังก์ชันภายใต้การทดสอบอย่างชาญฉลาด (โดยการปรับอินพุตให้เป็นเส้นทางการดำเนินการที่ยังไม่ได้สำรวจ)

instrumenting ไบนารีของคุณด้วย sanitizers (Address ฆ่าเชื้อ, Memory ฆ่าเชื้อหรือไม่ได้กำหนดพฤติกรรมฆ่าเชื้อ) แล้ว fuzzing มัน (โดยใช้อเมริกันฟัซซี่ลพบุรีตัวอย่าง) มีช่องโหว่เปิดในจำนวนของโปรแกรมสูงโปรไฟล์ดูตัวอย่างนี้บทความ LWN.net

เครื่องมือใหม่เหล่านั้นและเครื่องมือในอนาคตทั้งหมดนั้นไม่สามารถเข้าถึงคุณได้เว้นแต่คุณจะอัปเกรดคอมไพเลอร์ของคุณ

เมื่ออยู่บนคอมไพเลอร์ที่มีกำลังต่ำคุณกำลังวางหัวลงบนทรายและนิ้วมือข้ามที่ไม่พบช่องโหว่ หากผลิตภัณฑ์ของคุณเป็นเป้าหมายที่มีมูลค่าสูงฉันขอให้คุณลองพิจารณาอีกครั้ง


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


1
+1 สำหรับการรบกวนพูดถึงกรณีที่คอมไพเลอร์ใหม่สามารถมีความปลอดภัยมากกว่าการซ้อนทับกันใน 'b- แต่ UB เก่าที่ดีของฉัน' bandwagon ของคำตอบอื่น ๆ สิ่งนี้อยู่เหนือการปรับปรุงอื่น ๆ อีกมากมายที่พวกเขานำเสนอซึ่งไม่เกี่ยวข้องโดยตรงกับความปลอดภัย แต่ให้แรงผลักดันมากขึ้นเพื่อให้ทันสมัยพอสมควร
underscore_d

แม้ว่ามันจะรู้สึกเหมือนเรียกร้อง 'ความปลอดภัยผ่านความสับสน'; ข้อบกพร่องที่ส่งผลกระทบต่อคอมไพเลอร์เก่าเป็นที่รู้จักและเปิดเผยต่อสาธารณะ ในขณะที่ฉันยอมรับว่าคอมไพเลอร์ใหม่จะแนะนำข้อบกพร่องข้อบกพร่องเหล่านี้ยังไม่เป็นสาธารณะเช่นเดียวกับรุ่นก่อนหน้าซึ่งเป็นความปลอดภัยบางอย่างหากคุณกำลังอัปเดตแอปพลิเคชันบ่อยครั้ง
The6P4C

แชนด์เลอร์คาร์รั ธ น่ารักมากและพูดถึงสิ่งมหัศจรรย์เช่นนี้ ฉันจะแต่งงานกับเขาถ้าฉันทำได้
Daniel Kamil Kozar

46

รหัสที่คอมไพล์แล้วของคุณมีบั๊กที่อาจถูกโจมตีได้ ข้อบกพร่องมาจากสามแหล่ง: บักในซอร์สโค้ดของคุณ, บั๊กในคอมไพเลอร์และไลบรารี, และพฤติกรรมที่ไม่ได้กำหนดในซอร์สโค้ดของคุณที่คอมไพเลอร์เปลี่ยนเป็นบั๊ก (พฤติกรรมที่ไม่ได้กำหนดเป็นข้อบกพร่อง แต่ไม่ใช่ข้อบกพร่องในโค้ดที่คอมไพล์เช่น i = i ++; ใน C หรือ C ++ เป็นข้อบกพร่อง แต่ในโค้ดที่คอมไพล์ของคุณมันอาจเพิ่ม i 1 และเป็น Ok หรือตั้งค่า ฉันจะขยะและเป็นข้อผิดพลาด)

อัตราของบั๊กในโค้ดที่คอมไพล์ของคุณอยู่ในระดับต่ำเนื่องจากการทดสอบและการแก้ไขบั๊กเนื่องจากรายงานบั๊กของลูกค้า ดังนั้นอาจมีข้อผิดพลาดจำนวนมากในตอนแรก แต่มันก็ลดลง

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

ดังนั้นคุณจะมีข้อบกพร่องใหม่จำนวนมากในโค้ดที่รวบรวมของคุณ ข้อบกพร่องทั้งหมดที่แฮ็กเกอร์สามารถค้นหาและใช้ประโยชน์ได้ และถ้าคุณไม่ทำการทดสอบจำนวนมากและปล่อยให้รหัสของคุณกับลูกค้าเพื่อค้นหาข้อบกพร่องเป็นเวลานานมันจะปลอดภัยน้อยลง


6
ดังนั้นในคำอื่น ๆ ... ไม่มีวิธีที่ง่ายที่จะบอกปัญหาที่คอมไพเลอร์แนะนำและการเปลี่ยนสิ่งที่คุณทำคือรับปัญหาที่ไม่รู้จักชุดอื่น
Jeremy Kato

1
@JeremyKato: ดีมีบางกรณีที่คุณยังได้รับชุดที่แตกต่างของปัญหาที่ทราบ ฉันไม่แน่ใจว่าข้อบกพร่องด้านความปลอดภัยที่รู้จักมีอยู่ในคอมไพเลอร์เอง แต่เพื่อตัวอย่างที่เป็นรูปธรรมสมมติว่าการอัปเดตเป็นคอมไพเลอร์ใหม่หมายความว่ายังสามารถใช้ libc ล่าสุดได้ (ในขณะที่ใช้ตัวเก่าหมายถึงไม่สามารถทำได้ การทำเช่นนี้) แล้วคุณจะรู้ว่าคุณกำลังแก้ไขข้อบกพร่องนี้ในgetaddrinfo(): access.redhat.com/articles/2161461 ตัวอย่างนั้นไม่ใช่ข้อบกพร่องด้านความปลอดภัยของคอมไพเลอร์ แต่มีมากกว่า 10 ปีที่จะต้องมีข้อบกพร่องที่แน่นอน
Steve Jessop

2
Heh จริง ๆ แล้วข้อบกพร่องนั้นถูกนำมาใช้ในปี 2008 เท่านั้นดังนั้นผู้ถามอาจปลอดภัยจากมัน แต่ประเด็นของฉันไม่ได้เกี่ยวกับตัวอย่างเฉพาะนั่นคือมีข้อบกพร่องที่รู้จักอยู่แล้วซึ่ง toolchain แบบเก่าจะใส่ลงในโค้ดของคุณ ดังนั้นเมื่อคุณอัปเดตมันเป็นความจริงที่คุณแนะนำชุดใหม่ของราชวงศ์ แต่นั่นไม่ใช่สิ่งที่คุณทำ คุณเพียงแค่ต้องเดาว่าคุณมี "ความปลอดภัยมากขึ้น" ในข้อบกพร่องที่สำคัญที่รู้จักกันว่า toolchain ล่าสุดแก้ไขหรือไม่รับผลที่ไม่รู้จักจากการทอยลูกเต๋าอีกครั้งในพฤติกรรมที่ไม่ได้กำหนดในรหัสของคุณเอง
Steve Jessop

19

ถ้ามันไม่พังก็อย่าซ่อมมัน

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

อย่างไรก็ตามหากรหัสฐานเป็นแบบโบราณและมีการทำงานเพื่อลดจุดอ่อนของ K&R C ที่ใช้งานเช่นการขาดความปลอดภัยประเภท, ความไม่ปลอดภัยที่ไม่ปลอดภัย ฯลฯ คำถามที่หนักขึ้น " จะอัพเกรดคอมไพเลอร์ให้ทันสมัยมากขึ้น C99 / C11 มาตรฐานทำลายทุกอย่างเหรอ "

หากมีเส้นทางที่ชัดเจนในการโยกย้ายไปยังมาตรฐาน C ที่ใหม่กว่าซึ่งอาจชักนำให้เกิดผลข้างเคียงได้อาจเป็นการดีที่สุดที่จะลองใช้ codebase เก่าประเมินทางเลือกและทำการตรวจสอบประเภทพิเศษตรวจสอบสติและพิจารณาว่าการอัพเกรดเป็น คอมไพเลอร์รุ่นใหม่มีผลกระทบกับชุดข้อมูลอินพุต / เอาต์พุต

จากนั้นคุณสามารถแสดงให้หัวหน้าของคุณ " นี่คือฐานรหัสที่ได้รับการปรับปรุงสร้างใหม่และสอดคล้องกับมาตรฐาน C99 / C11 ที่เป็นที่ยอมรับในอุตสาหกรรม ... "

นั่นคือการเล่นการพนันที่จะต้องมีการชั่งน้ำหนักขึ้นบนอย่างระมัดระวัง , ความต้านทานการเปลี่ยนแปลงอาจแสดงมีอยู่ในสภาพแวดล้อมที่และอาจปฏิเสธที่จะสัมผัสสิ่งใหม่

แก้ไข

เพิ่งกลับมาไม่กี่นาทีก็รู้ว่านี่รหัส K&R ที่สร้างขึ้นสามารถทำงานบนแพลตฟอร์ม 16 บิตโอกาสที่การอัพเกรดเป็นคอมไพเลอร์ที่ทันสมัยมากขึ้นอาจทำลายฐานรหัสได้จริง ๆ แล้วคิดในแง่ของสถาปัตยกรรมรหัส 32 บิตจะถูกสร้างขึ้น สิ่งนี้อาจมีผลข้างเคียงที่ตลกเกี่ยวกับโครงสร้างที่ใช้สำหรับชุดข้อมูลอินพุต / เอาต์พุตซึ่งเป็นอีกหนึ่งปัจจัยใหญ่ที่ต้องชั่งน้ำหนักอย่างระมัดระวัง

นอกจากนี้เนื่องจาก OP ได้กล่าวถึงการใช้ Visual Studio 2008 เพื่อสร้าง codebase การใช้ gcc อาจทำให้เกิดสภาพแวดล้อมทั้ง MinGW หรือ Cygwin ซึ่งอาจมีผลกระทบต่อการเปลี่ยนแปลงสภาพแวดล้อมเว้นแต่เป้าหมายสำหรับ Linux นั้นจะเป็น คุ้มค่ากับการถ่ายภาพอาจต้องมีสวิตช์เพิ่มเติมไปยังคอมไพเลอร์เพื่อลดเสียงรบกวนบนฐานรหัส K&R เก่าสิ่งสำคัญอื่น ๆ คือการทดสอบจำนวนมากเพื่อให้แน่ใจว่าไม่มีฟังก์ชั่นที่ใช้งานไม่ได้


รหัสเดียวกันนี้สร้างขึ้นโดย Visual Studio 2008 สำหรับเป้าหมาย Windows และ MSVC ยังไม่รองรับ C99 หรือ C11 (ฉันไม่ทราบว่า MSVC รุ่นใหม่ทำ) และฉันสามารถสร้างมันบนกล่อง Linux โดยใช้ GCC ล่าสุด ดังนั้นหากเราเพิ่งจะลดลงใน GCC รุ่นใหม่มันอาจจะสร้างได้ดีเหมือนเดิม
Calmarius

@Calarius ขอบคุณสำหรับหัวขึ้นบางทีมันอาจจะดีที่สุดในการแก้ไขคำถามของคุณเพื่อรวมความคิดเห็นนั่นเป็นเรื่องสำคัญ :) และควรจะอยู่ที่นั่น D
t0mm13b

@Calarius ได้แก้ไขคำตอบของฉันซึ่งเป็นความคิดของฉันในคำถามที่ปรับปรุงใหม่
t0mm13b

2
“ อาจจะทำงานบนแพลตฟอร์ม 16 บิตมีโอกาสอัพเกรดเป็นคอมไพเลอร์ที่ทันสมัยมากขึ้นจริงอาจทำลายรหัสฐานฉันกำลังคิดในแง่ของสถาปัตยกรรมรหัส 32 บิต” ฉันไม่คิดว่าคำถามเกี่ยวกับการย้ายรหัสไปยังการใช้งานที่กำหนดใหม่ พารามิเตอร์
Pascal Cuoq

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

9

การใช้คอมไพเลอร์ C ตัวเก่าสามารถลดความปลอดภัยของโปรแกรมที่คอมไพล์ได้ไหม

แน่นอนมันสามารถถ้าคอมไพเลอร์เก่ามีข้อบกพร่องที่รู้จักที่คุณรู้ว่าจะส่งผลกระทบต่อโปรแกรมของคุณ

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

หากคุณพบว่าไม่มีข้อผิดพลาดของคอมไพเลอร์ที่จะส่งผลกระทบต่อโปรแกรมของคุณให้อัปเดต GCC เพื่อให้ดูเหมือนเป็นเรื่องหวาดระแวง คุณต้องจำไว้ว่าเวอร์ชั่นใหม่อาจมีบั๊กใหม่ที่ยังไม่ได้ค้นพบ มีการเปลี่ยนแปลงมากมายเมื่อเร็ว ๆ นี้ด้วยการสนับสนุน GCC 5 และ C11

ดังที่กล่าวไว้ว่าโค้ดที่เขียนในยุค 80 น่าจะเต็มไปด้วยความปลอดภัยและเชื่อมั่นในพฤติกรรมที่กำหนดไว้ไม่ดีนัก เรากำลังพูดถึงมาตรฐานเบื้องต้น C ที่นี่


6
ฉันไม่คิดว่ามันจะเป็นความหวาดระแวง ฉันคิดว่า OP พยายามคิดหาเหตุผลเพื่อโน้มน้าวเจ้านายของเขา อาจ OP ต้องการคอมไพเลอร์ใหม่เพราะทำให้ asm ดีขึ้น (รวมถึงการเพิ่มประสิทธิภาพ cross-file ด้วย LTO) มีการวินิจฉัย / คำเตือนที่มีประโยชน์มากขึ้นและอนุญาตคุณสมบัติและไวยากรณ์ภาษาที่ทันสมัย (เช่น C11 stdatomic)
Peter Cordes

9

มีความเสี่ยงด้านความปลอดภัยที่ผู้พัฒนาที่ประสงค์ร้ายสามารถแอบเข้าไปทางหลังผ่านบั๊กของคอมไพเลอร์ ขึ้นอยู่กับปริมาณของข้อบกพร่องที่รู้จักในคอมไพเลอร์ที่ใช้งานแบ็คดอร์อาจดูไม่เด่นมากขึ้นหรือน้อยลง (ไม่ว่าในกรณีใด ๆ จุดคือรหัสนั้นถูกต้องแม้ว่าในระดับแหล่งที่ซับซ้อน คอมไพเลอร์ที่ไม่ใช่บั๊กกี้จะไม่พบแบ็คดอร์เนื่องจากแบ็คดอร์ไม่มีอยู่ในเงื่อนไขเหล่านี้) สำหรับจุดปฏิเสธพิเศษผู้พัฒนาที่เป็นอันตรายอาจค้นหาข้อบกพร่องของคอมไพเลอร์ที่ไม่รู้จักก่อนหน้านี้ด้วยตนเอง คุณภาพของลายพลางจะขึ้นอยู่กับการเลือกข้อบกพร่องของคอมไพเลอร์ที่พบ

การโจมตีครั้งนี้จะแสดงบน sudo โปรแกรมในบทความนี้ bcrypt เขียนติดตามที่ดีสำหรับminifiers Javascript

นอกเหนือจากความกังวลนี้วิวัฒนาการของคอมไพเลอร์ C ที่ได้รับการใช้ประโยชน์จากพฤติกรรมที่ไม่ได้กำหนดมากขึ้นและมากขึ้นและมากขึ้นในเชิงรุกเพื่อให้รหัส C เก่าที่ถูกเขียนขึ้นในความเชื่อที่ดีจะจริงจะปลอดภัยมากขึ้นรวบรวมกับคอมไพเลอร์ C จากเวลาหรือรวบรวมที่ -O0 (แต่มีการเพิ่มประสิทธิภาพ UB ที่หาประโยชน์จากโปรแกรมใหม่) ในคอมไพเลอร์เวอร์ชั่นใหม่แม้ที่ -O0 )


7

คอมไพเลอร์รุ่นเก่าอาจไม่มีการป้องกันการโจมตีจากการแฮ็คที่รู้จัก สแต็คยอดเยี่ยมการป้องกันตัวอย่างเช่นไม่ได้ถูกนำมาใช้จน GCC 4.1 ดังนั้นใช่โค้ดที่คอมไพล์ด้วยคอมไพเลอร์รุ่นเก่าอาจมีช่องโหว่ในวิธีที่คอมไพเลอร์รุ่นใหม่ป้องกัน


6

ด้านที่จะต้องกังวลอีกประการหนึ่งเกี่ยวกับการเป็นผู้พัฒนาของโค้ดใหม่

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

คอมไพเลอร์รุ่นเก่ามีคุณสมบัติที่น้อยลง (รวมถึงคุณสมบัติภาษา!) และไม่ปรับให้เหมาะสมเช่นกัน โปรแกรมเมอร์จะเจาะช่องโหว่เหล่านี้ - เช่นการนำคุณลักษณะที่หายไปกลับมาใช้ใหม่หรือเขียนโค้ดที่ฉลาดซึ่งคลุมเครือ แต่ทำงานได้เร็วขึ้น - สร้างโอกาสใหม่สำหรับการสร้างข้อบกพร่องที่ละเอียดอ่อน


5

Nope

เหตุผลนั้นเรียบง่ายคอมไพเลอร์เก่าอาจมีข้อบกพร่องและการใช้ประโยชน์เก่า แต่คอมไพเลอร์ใหม่จะมีข้อบกพร่องและการหาประโยชน์ใหม่

คุณไม่ได้ "แก้ไข" ข้อบกพร่องใด ๆ โดยการอัพเกรดเป็นคอมไพเลอร์ใหม่ การสลับข้อบกพร่องเก่าและการหาช่องโหว่เพื่อหาจุดบกพร่องใหม่และช่องโหว่


3
สิ่งเหล่านี้ดูเหมือนจะง่ายมาก: คอมไพเลอร์ใหม่อาจมีจุดอ่อน แต่ฉันคาดว่ามันจะน้อยกว่าคอมไพเลอร์เก่าและมีแนวโน้มที่จะตรวจพบช่องโหว่ของโค้ดหลาย ๆ
PJTraill

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

เครื่องมือที่ช่วยค้นหาข้อผิดพลาดได้รับการปรับปรุงอย่างมากตั้งแต่ต้น GCC และเครื่องมือเหล่านี้ (การวิเคราะห์แบบคงที่การวิเคราะห์แบบไดนามิกของโค้ด / sanitisers, fuzzers เป็นต้น) ได้ถูกนำไปใช้กับโค้ดคอมไพเลอร์เช่นกันเพื่อช่วยปรับปรุงคุณภาพ มันยากมากที่จะหาบั๊กทุกประเภทในยุค GCC 2 การเปรียบเทียบข้อผิดพลาดของคอมไพเลอร์มากกว่ารุ่น - ดูหน้า 7: cs.utah.edu/~regehr/papers/pldi11-preprint.pdf GCC 4.5 และ LLVM 2.8 (ล่าสุดที่เผยแพร่) มีข้อบกพร่องน้อยที่สุดจาก fuzzing
Jetski S-type

2

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


0

คำถามของคุณแบ่งออกเป็นสองส่วน:

  • อย่างชัดเจน:“ มีความเสี่ยงมากขึ้นในการใช้คอมไพเลอร์รุ่นเก่าหรือไม่ (มากหรือน้อยกว่าในชื่อของคุณ)
  • โดยนัย:“ ฉันจะโน้มน้าวให้ฝ่ายจัดการอัพเกรดได้อย่างไร”

บางทีคุณสามารถตอบได้ทั้งคู่โดยหาข้อบกพร่องที่หาประโยชน์ได้ในฐานโค้ดที่มีอยู่ของคุณและแสดงว่าคอมไพเลอร์รุ่นใหม่จะตรวจพบ แน่นอนผู้บริหารของคุณอาจพูดว่า "คุณพบว่ามีคอมไพเลอร์เก่า" แต่คุณสามารถชี้ให้เห็นว่ามันต้องใช้ความพยายามอย่างมาก หรือคุณเรียกใช้ผ่านคอมไพเลอร์ใหม่เพื่อค้นหาช่องโหว่จากนั้นใช้ประโยชน์จากมันหากคุณสามารถ / อนุญาตให้คอมไพล์โค้ดด้วยคอมไพเลอร์ใหม่ คุณอาจต้องการความช่วยเหลือจากแฮ็กเกอร์ที่เป็นมิตร แต่ขึ้นอยู่กับการไว้วางใจพวกเขาและความสามารถ / ได้รับอนุญาตให้แสดงรหัส (และใช้คอมไพเลอร์ใหม่)

แต่ถ้าระบบของคุณไม่ถูกแฮ็คคุณอาจสนใจว่าการอัพเกรดคอมไพเลอร์จะเพิ่มประสิทธิภาพของคุณหรือไม่: การวิเคราะห์รหัส MSVS 2013 มักจะพบข้อบกพร่องที่อาจเกิดขึ้นเร็วกว่า MSVS 2010 และสนับสนุน C99 / C11 มากขึ้น - ไม่แน่ใจว่ามันทำอย่างเป็นทางการหรือไม่ แต่การประกาศสามารถทำตามคำสั่งได้และคุณสามารถประกาศตัวแปรในfor-loops

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.