retpoline คืออะไรและทำงานอย่างไร


244

เพื่อลดกับเคอร์เนลหรือหน่วยความจำการเปิดเผยกระบวนการข้าม (คนปีศาจโจมตี), ลินุกซ์เคอร์เนล1จะได้รับการรวบรวมกับตัวเลือกใหม่ , -mindirect-branch=thunk-externแนะนำให้รู้จักกับgccการดำเนินการโทรทางอ้อมผ่านสิ่งที่เรียกว่าretpoline

สิ่งนี้ดูเหมือนจะเป็นคำที่ประดิษฐ์ขึ้นใหม่เนื่องจากการค้นหาของ Google เปิดใช้งานเมื่อไม่นานมานี้เท่านั้น (โดยทั่วไปแล้วทั้งหมดในปี 2561)

retpoline คืออะไรและป้องกันการเปิดเผยข้อมูลเคอร์เนลล่าสุดได้อย่างไร


1มันไม่ได้เป็นลินุกซ์ที่เฉพาะเจาะจง - โครงสร้างที่คล้ายกันหรือเหมือนกันดูเหมือนจะใช้เป็นส่วนหนึ่งของกลยุทธ์การลดผลกระทบในระบบปฏิบัติการอื่น ๆ


6
บทความสนับสนุนที่น่าสนใจจาก Google
sgbj

2
โอ้มันเด่นชัด / ˌtræmpəˈlin / (อเมริกัน) หรือ / ˈtræmpəˌliːn / (อังกฤษ)
Walter Tross

2
คุณอาจพูดถึงว่านี่คือเคอร์เนลLinuxแม้ว่าจะgccชี้ไปในทางนั้น! ฉันไม่รู้จัก lkml.org/lkml/2018/1/3/780เช่นเดียวกับในเว็บไซต์ลิสต์การส่งเมลเคอร์เนลของลินุกซ์แม้แต่ครั้งเดียวที่ฉันดูที่นั่น
PJTraill

@PJTraill - เพิ่มแท็กเคอร์เนล Linux
RichVel

@PJTraill - จุดดีฉันปรับปรุงข้อความคำถาม โปรดทราบว่าฉันเห็นมันครั้งแรกในเคอร์เนลลินุกซ์เพราะมันเป็นกระบวนการพัฒนาที่ค่อนข้างเปิด แต่ไม่ต้องสงสัยเลยว่าเทคนิคเดียวกันหรือคล้ายกันนี้ถูกใช้เป็นเครื่องมือบรรเทาผลกระทบในสเปกตรัมของระบบปฏิบัติการโอเพ่นซอร์สและปิด ดังนั้นฉันจึงไม่เห็นว่านี่เป็นลินุกซ์โดยเฉพาะ แต่การเชื่อมโยงนั้นแน่นอน
BeeOnRope

คำตอบ:


158

บทความที่กล่าวถึงโดย sgbj ในความคิดเห็นที่เขียนโดย Paul Turner ของ Google จะอธิบายรายละเอียดต่อไปนี้ แต่ฉันจะให้มัน:

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

วิธีการพื้นฐานสามารถดูได้ในสาขาเคอร์เนลของ Andi Kleenเพื่อจัดการกับปัญหานี้:

แนะนำการ__x86.indirect_thunkโทรใหม่ที่โหลดเป้าหมายการโทรที่มีที่อยู่หน่วยความจำ (ซึ่งฉันจะโทรADDR) จะถูกเก็บไว้ที่ด้านบนของสแต็กและดำเนินการกระโดดโดยใช้RETคำสั่ง thunk นั้นถูกเรียกโดยใช้แมโค NOSPEC_JMP / CALLซึ่งถูกใช้เพื่อแทนที่การโทรและข้ามทางอ้อมจำนวนมาก (ถ้าไม่ใช่ทั้งหมด) แมโครจะวางเป้าหมายการโทรไว้บนสแต็กและตั้งค่าที่อยู่ผู้ส่งคืนอย่างถูกต้องหากจำเป็น (หมายเหตุการควบคุมการไหลที่ไม่ใช่เชิงเส้น):

.macro NOSPEC_CALL target
    jmp     1221f            /* jumps to the end of the macro */
1222:
    push    \target          /* pushes ADDR to the stack */
    jmp __x86.indirect_thunk /* executes the indirect jump */
1221:
    call    1222b            /* pushes the return address to the stack */
.endm

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

ตัวตนมีลักษณะดังต่อไปนี้:

    call retpoline_call_target
2:
    lfence /* stop speculation */
    jmp 2b
retpoline_call_target:
    lea 8(%rsp), %rsp 
    ret

โฟลว์การควบคุมอาจทำให้สับสนเล็กน้อยที่นี่ดังนั้นให้ฉันอธิบาย:

  • call ดันตัวชี้คำสั่งปัจจุบัน (เลเบล 2) ไปยังสแต็ก
  • leaเพิ่ม 8 ให้กับสแต็คพอยน์เตอร์ซึ่งละทิ้ง quadword ที่พุชล่าสุดซึ่งเป็นที่อยู่ผู้ส่งคืนล่าสุด (ไปยังเลเบล 2) ได้อย่างมีประสิทธิภาพ หลังจากนี้จุดสูงสุดของสแต็กจะชี้ไปที่ที่อยู่ผู้ส่งที่แท้จริงของ ADDR อีกครั้ง
  • retข้ามไป*ADDRและรีเซ็ตตัวชี้สแต็กเป็นจุดเริ่มต้นของสแตกการโทร

*ADDRในท้ายที่สุดพฤติกรรมทั้งหมดนี้เป็นจริงเทียบเท่ากับการกระโดดโดยตรงกับ ประโยชน์อย่างหนึ่งที่เราได้รับคือตัวทำนายสาขาที่ใช้สำหรับคำสั่งส่งคืน (Return Stack Buffer, RSB) เมื่อดำเนินการcallคำสั่งสมมติว่าretคำสั่งที่เกี่ยวข้องจะข้ามไปที่ป้ายกำกับ 2

ส่วนหลังจากฉลาก 2 ไม่เคยถูกประหารจริงมันเป็นเพียงแค่วงวนไม่สิ้นสุดที่ตามทฤษฎีแล้วจะเติมคำJMPแนะนำ โดยการใช้LFENCEงานPAUSEหรือมากกว่านั้นคำสั่งที่ทำให้ท่อส่งคำสั่งหยุดการทำงานของ CPU ไม่ให้สิ้นเปลืองพลังงานและเวลาในการดำเนินการเก็งกำไร นี่เป็นเพราะในกรณีที่การเรียกไปที่ retpoline_call_target จะกลับมาตามปกติLFENCEจะเป็นคำสั่งต่อไปที่จะดำเนินการ นี่คือสิ่งที่ตัวพยากรณ์สาขาจะทำนายตามที่อยู่ผู้ส่งคืนเดิม (ฉลาก 2)

อ้างจากคู่มือสถาปัตยกรรมของ Intel:

คำแนะนำต่อไปนี้อาจถูกดึงมาจากหน่วยความจำ LFENCE ก่อน LFENCE แต่จะไม่ทำงานจนกว่า LFENCE จะเสร็จสิ้น

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

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

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

  • ตัวพยากรณ์สาขาทางอ้อมของ CPU ของ Intel ใช้เฉพาะคำสั่งแหล่งกำเนิดต่ำสุด 12 บิตเท่านั้นดังนั้นจึงเป็นเรื่องง่ายที่จะทำให้พิษการทำนายที่เป็นไปได้ทั้งหมด 2 ^ 12 ด้วยที่อยู่หน่วยความจำที่ผู้ใช้ควบคุม สิ่งเหล่านี้สามารถเมื่อคาดการณ์การกระโดดทางอ้อมภายในเคอร์เนลจะดำเนินการอย่างพิเศษด้วยสิทธิ์เคอร์เนล การใช้ช่องสัญญาณด้านเวลาแคชคุณสามารถรั่วไหลหน่วยความจำเคอร์เนลโดยพลการ

อัปเดต: ในรายชื่อส่งเมลเคอร์เนลมีการสนทนาอย่างต่อเนื่องที่ทำให้ฉันเชื่อว่าเรโทรโพลิสไม่ได้ลดปัญหาการคาดคะเนสาขาอย่างเต็มที่เช่นเมื่อ Return Stack Buffer (RSB) หมดเปล่าสถาปัตยกรรม Intel ล่าสุด (Skylake +) ไปยัง Branch Target Buffer (BTB):

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


ฉันไม่คิดว่าคำสั่ง LFENCE นั้นสำคัญการใช้งานของ Google จะใช้คำสั่ง PAUSE แทน support.google.com/faqs/answer/7625886โปรดทราบว่าเอกสารที่คุณพูดว่า "จะไม่ดำเนินการ" จะไม่ดำเนินการ "จะไม่ถูกดำเนินการโดยเฉพาะ"
Ross Ridge

1
จากหน้าคำถามที่พบบ่อยของ Google: "คำแนะนำการหยุดชั่วคราวในลูปการเก็งกำไรของเราด้านบนนั้นไม่จำเป็นสำหรับความถูกต้อง แต่หมายความว่าการประมวลผลการเก็งกำไรที่ไม่มีประสิทธิผลนั้นใช้หน่วยการทำงานที่น้อยลงในโปรเซสเซอร์" ดังนั้นจึงไม่สนับสนุนข้อสรุปของคุณว่า LFENCE คือกุญแจสำคัญที่นี่
Ross Ridge

@RossRidge ฉันเห็นด้วยบางส่วนสำหรับฉันนี่ดูเหมือนว่าการใช้งานที่เป็นไปได้สองอย่างของ infinite loop ที่บอกใบ้ให้ซีพียูไม่เจาะจงรันโค้ดตามหลัง PAUSE / LFENCE อย่างไรก็ตามหาก LFENCE ถูกดำเนินการอย่างเก็งกำไรและไม่ย้อนกลับเนื่องจากการเก็งกำไรนั้นถูกต้องสิ่งนี้จะขัดแย้งกับการอ้างสิทธิ์ว่าจะถูกดำเนินการเฉพาะเมื่อการโหลดหน่วยความจำเสร็จสิ้น (มิฉะนั้นชุดคำสั่งทั้งชุดที่ถูกดำเนินการโดยเก็งกำไรจะต้องถูกนำกลับมาและดำเนินการอีกครั้งเพื่อทำตามข้อกำหนด)
Tobias Ribizel

1
นี่คือข้อดีของpush/ retว่าไม่ทำให้เกิดความไม่สมดุลสแต็คที่อยู่ผู้ส่งคืน มีหนึ่ง mispredict (ไปlfenceก่อนที่จะใช้ที่อยู่ผู้ส่งจริง) แต่ใช้call+ การปรับrspสมดุลให้retดีขึ้น
Peter Cordes

1
อ๊ะได้เปรียบกว่า push / ret(ในความคิดเห็นล่าสุดของฉัน) Re: การแก้ไขของคุณ: RSB underflow ควรจะเป็นไปไม่ได้เพราะ retpoline callรวมถึง หากเคอร์เนลมีการเปลี่ยนแปลงบริบทเราจะดำเนินการกับ RSB ที่เตรียมไว้จากcallในตัวกำหนดตารางเวลา แต่บางทีตัวจัดการขัดจังหวะอาจจบลงด้วยพอretที่จะล้าง RSB
Peter Cordes

46

retpolineถูกออกแบบมาเพื่อป้องกันการฉีดเป้าหมายสาขา ( CVE-2017-5715 ) ใช้ประโยชน์จาก นี่คือการโจมตีที่คำสั่งสาขาทางอ้อมในเคอร์เนลถูกนำมาใช้เพื่อบังคับให้มีการดำเนินการเก็งกำไรของรหัสโดยพลการ รหัสที่เลือกเป็น "แกดเจ็ต" ที่มีประโยชน์ต่อผู้โจมตี ตัวอย่างเช่นรหัสสามารถเลือกเพื่อที่จะรั่วไหลข้อมูลเคอร์เนลผ่านวิธีที่มันมีผลต่อแคช retpoline ป้องกันการโจมตีนี้เพียงแค่เปลี่ยนคำสั่งสาขาทางอ้อมทั้งหมดด้วยคำแนะนำการส่งคืน

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

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

โปรดทราบว่า retpoline ไม่ได้ป้องกันการเปิดเผยข้อมูลเคอร์เนลโดยตรง แต่จะป้องกันไม่ให้ใช้คำสั่งสาขาทางอ้อมเพื่อดำเนินการแกดเจ็ตแบบพิเศษที่จะเปิดเผยข้อมูล หากผู้โจมตีสามารถหาวิธีอื่นในการดำเนินการแกดเจ็ตอย่างพิเศษจากนั้น retpoline จะไม่ป้องกันการโจมตี

เอกสารSpectre Attacks: Exploiting Execution Executionโดย Paul Kocher, Daniel Genkin, Daniel Gruss, Werner Haas, Mike Hamburg, Moritz Lipp, Stefan Mangard, โทมัส Prescher, Michael Schwarz และ Yuval Yarom ให้ภาพรวมต่อไปนี้ :

ใช้ประโยชน์จากสาขาทางอ้อม การวาดภาพจากการเขียนโปรแกรมเชิงกลับ (ROP) ในวิธีนี้ผู้โจมตีเลือกอุปกรณ์จากพื้นที่ที่อยู่ของผู้ที่ตกเป็นเหยื่อและมีอิทธิพลต่อผู้ที่ตกเป็นเหยื่อในการดำเนินการแกดเจ็ตอย่างพิเศษ ซึ่งแตกต่างจาก ROP ผู้โจมตีไม่ต้องพึ่งพาช่องโหว่ในรหัสเหยื่อ ผู้โจมตีทำการฝึกซ้อม Branch Target Buffer (BTB) แทนการคาดคะเนสาขาจากคำสั่งสาขาทางอ้อมไปยังที่อยู่ของแกดเจ็ตส่งผลให้เกิดการเก็งกำไรของแกดเจ็ต ในขณะที่คำสั่งที่ดำเนินการโดยเฉพาะถูกทอดทิ้งผลกระทบที่มีต่อแคชจะไม่เปลี่ยนกลับ เอฟเฟกต์เหล่านี้สามารถใช้งานโดยแกดเจ็ตเพื่อรั่วไหลข้อมูลสำคัญ เราแสดงให้เห็นว่าด้วยการเลือกใช้อุปกรณ์อย่างระมัดระวังวิธีนี้สามารถใช้ในการอ่านหน่วยความจำโดยพลการจากเหยื่อ

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

รายการบล็อกชื่อการอ่านหน่วยความจำที่มีสิทธิพิเศษพร้อมช่องด้านข้างโดยทีมศูนย์โครงการที่ Google แสดงตัวอย่างอีกวิธีที่การใช้การฉีดเป้าหมายสาขาเพื่อสร้างช่องโหว่ที่ทำงานได้


9

คำถามนี้ถูกถามเมื่อไม่นานมานี้และสมควรได้รับคำตอบที่ใหม่กว่า

บทสรุปผู้บริหาร :

ลำดับ“ Retpoline” เป็นโครงสร้างซอฟต์แวร์ที่อนุญาตให้กิ่งทางอ้อมแยกออกจากการดำเนินการเก็งกำไร สิ่งนี้อาจนำไปใช้เพื่อปกป้องไบนารีที่มีความละเอียดอ่อน (เช่นระบบปฏิบัติการหรือการใช้งานไฮเปอร์ไวเซอร์) จากการโจมตีเป้าหมายของการโจมตีด้วยกิ่งสาขากับกิ่งทางอ้อม

คำว่า " ret poline " เป็นกระเป๋าหิ้วของคำว่า "return" และ "trampoline" เหมือนกับการปรับปรุง " rel poline " นั้นได้รับการประกาศเกียรติคุณจาก "สายสัมพันธ์" และ "trampoline" มันเป็นโครงสร้างแทรมโพลีนที่สร้างขึ้นโดยใช้การคืนค่าซึ่งช่วยให้มั่นใจได้ว่าการดำเนินการเก็งกำไรที่เกี่ยวข้องจะ“ เด้ง” อย่างไม่มีที่สิ้นสุด

เพื่อลดการเปิดเผยเคอร์เนลหรือการเปิดเผยหน่วยความจำข้ามกระบวนการ (การโจมตีจาก Spectre), เคอร์เนล Linux [1]จะถูกรวบรวมด้วยตัวเลือกใหม่-mindirect-branch=thunk-externแนะนำให้ใช้ gcc เพื่อทำการโทรทางอ้อมผ่าน retpoline ที่เรียกว่า

[1] ไม่ใช่ลินุกซ์โดยเฉพาะอย่างไรก็ตาม - โครงสร้างที่คล้ายกันหรือเหมือนกันดูเหมือนจะใช้เป็นส่วนหนึ่งของกลยุทธ์การลดผลกระทบในระบบปฏิบัติการอื่น ๆ

การใช้ตัวเลือกคอมไพเลอร์นี้เพียงป้องกันผี V2ในการประมวลผลได้รับผลกระทบที่มีการอัปเดตเฟิร์มแวที่จำเป็นสำหรับการ CVE-2017-5715 มันจะ 'ทำงาน ' บนโค้ดใด ๆ (ไม่ใช่แค่เคอร์เนล) แต่โค้ดที่มี "secret" เท่านั้นที่คุ้มค่าที่จะถูกโจมตี

สิ่งนี้ดูเหมือนจะเป็นคำที่ประดิษฐ์ขึ้นใหม่เนื่องจากการค้นหาของ Google เปิดใช้งานเมื่อไม่นานมานี้เท่านั้น (โดยทั่วไปแล้วทั้งหมดในปี 2561)

คอมไพเลอร์ LLVMมี-mretpolineสวิทช์ตั้งแต่ก่อนที่ 4 มกราคม 2018 วันนั่นคือเมื่อช่องโหว่ที่ถูกรายงานครั้งแรกสาธารณะ GCCเปิดตัวแพตช์วันที่ 7 มกราคม 2018

วันที่ CVE แสดงให้เห็นว่าช่องโหว่นั้น 'ถูกค้นพบ ' ในปี 2017 แต่มันส่งผลกระทบต่อตัวประมวลผลบางส่วนที่ผลิตในช่วงสองทศวรรษที่ผ่านมา

retpoline คืออะไรและป้องกันการเปิดเผยข้อมูลเคอร์เนลล่าสุดได้อย่างไร

ก่อนคำจำกัดความไม่กี่:

  • แทรมโพลีน - บางครั้งเรียกว่าแทรมโพลีเมอร์กระโดดทางอ้อมคือตำแหน่งหน่วยความจำที่เก็บที่อยู่ซึ่งชี้ไปที่รูทีนการบริการขัดจังหวะ I / O รูทีน ฯลฯ การประหารกระโดดเข้าไปในแทรมโพลีนแล้วกระโดดออก GCC ได้รองรับการใช้งานฟังก์ชั่นซ้อนกันแบบดั้งเดิมโดยการสร้างแทรมโพลีนที่สามารถเรียกใช้งานได้ ณ รันไทม์เมื่อมีการใช้ที่อยู่ของฟังก์ชันซ้อน นี่เป็นโค้ดชิ้นเล็ก ๆ ซึ่งปกติจะอยู่บนสแต็กในสแต็กเฟรมของฟังก์ชันที่มีอยู่ แทรมโพลีนจะทำการโหลดรีจิสเตอร์โซ่แบบคงที่แล้วข้ามไปยังที่อยู่จริงของฟังก์ชันซ้อน

  • Thunk - thunk เป็นรูทีนย่อยที่ใช้เพื่อฉีดการคำนวณเพิ่มเติมลงในรูทีนย่อยอื่น ส่วนใหญ่จะใช้ Thunks เพื่อชะลอการคำนวณจนกว่าจะต้องการผลลัพธ์หรือเพื่อแทรกการดำเนินการที่จุดเริ่มต้นหรือจุดสิ้นสุดของรูทีนย่อยอื่น

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

มากประมาณเป็นretpolineเป็นผ้าใบที่มีผลตอบแทนเป็นthunkเพื่อ ' ที่ริบ ' memoizationในตัวทำนายสาขาทางอ้อม

แหล่ง : retpoline รวมถึงคำสั่ง PAUSE สำหรับ Intel แต่คำสั่ง LFENCE นั้นจำเป็นสำหรับ AMD เนื่องจากโปรเซสเซอร์นั้นคำสั่ง PAUSE ไม่ใช่คำสั่งต่อเนื่องดังนั้นการหยุด / jmp จะใช้พลังงานส่วนเกินเนื่องจากคาดว่าจะรอส่งคืน เพื่อคาดคะเนผิดกับเป้าหมายที่ถูกต้อง

ArsTechnicaมีคำอธิบายง่ายๆของปัญหา:

"โปรเซสเซอร์แต่ละตัวมีพฤติกรรมสถาปัตยกรรม (พฤติกรรมที่เป็นเอกสารซึ่งอธิบายวิธีการทำงานของคำสั่งและโปรแกรมเมอร์นั้นขึ้นอยู่กับการเขียนโปรแกรมของพวกเขา) และพฤติกรรม microarchitectural (วิธีการใช้งานจริงของสถาปัตยกรรมพฤติกรรม) สิ่งเหล่านี้สามารถแตกต่างกัน ตัวอย่างเช่นในเชิงสถาปัตยกรรมโปรแกรมที่โหลดค่าจากที่อยู่เฉพาะในหน่วยความจำจะรอจนกว่าจะทราบที่อยู่ก่อนที่จะพยายามดำเนินการโหลด Microarchitecturally อย่างไรก็ตามโปรเซสเซอร์อาจพยายามคาดเดาที่อยู่เพื่อคาดเดาว่ามันจะเริ่ม การโหลดค่าจากหน่วยความจำ (ซึ่งช้า) ก่อนที่จะแน่ใจว่าควรใช้ที่อยู่ใด

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

จากบทความของ Intel: " Retpoline: A Branch Target Injection Mitigation " ( .PDF ):

"ลำดับ retpoline ป้องกันการดำเนินการเก็งกำไรของโปรเซสเซอร์จากการใช้" การพยากรณ์ทางอ้อม "(ทางเดียวในการทำนายการไหลของโปรแกรม) เพื่อคาดการณ์ที่อยู่ที่ควบคุมโดยการใช้ประโยชน์ (องค์ประกอบที่น่าพอใจ 4 องค์ประกอบห้าองค์ประกอบการฉีดเป้าหมายสาขา) ) ใช้ประโยชน์จากองค์ประกอบที่ระบุไว้ข้างต้น) ".

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

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