การใช้ libc สำรองกับ ld-linux.so hacks; วิธีทำความสะอาด?


13

ฉันมีระบบดั้งเดิมที่มี glibc ที่เก่ามากซึ่งเราไม่สามารถอัพเกรดได้โดยไม่ต้องมีการทดสอบ / ตรวจสอบความถูกต้อง

ฉันจำเป็นต้องเรียกใช้โปรแกรมใหม่ (เช่น Java 1.7) บนระบบนั้นหลายครั้งแล้ว ฉันเลือกโซลูชัน chroot ที่ฉันจัดเก็บ libs ที่จำเป็นทั้งหมดและเรียกใช้บริการใน chroot

แม้ว่า chroot จะมีข้อ จำกัด มากและฉันอยากจะลองแก้ปัญหาด้วย LD_LIBRARY_PATH น่าเสียดายที่ฉันได้รับข้อผิดพลาดlibc.so.6: cannot handle TLS dataเมื่อฉันลองทำ

ปรากฎว่าฉันต้องการ/lib/ld-linux.so.2จาก chroot เช่นกัน งานนี้:

LD_LIBRARY_PATH=/home/chroot/lib /home/chroot/lib/ld-linux.so.2 /home/chroot/bin/program

อย่างไรก็ตามjavaเกียดเคล็ดลับของฉันโดยการตรวจสอบ/proc/self/cmdlineเพื่อกำหนดที่จะโหลดห้องสมุดจากซึ่งล้มเหลวหากไบนารีไม่ได้ชื่อว่า 'bin / java' นอกจากนี้ java เรียกใช้ตัวเองในระหว่างการเริ่มต้นปัญหาที่ซับซ้อนมากขึ้น

ในความพยายามครั้งสุดท้ายที่จะทำให้งานนี้ฉันเปิดไบนารี Java ด้วยโปรแกรมแก้ไขฐานสิบหกและแทนที่สตริง/lib/ld-linux.so.2ด้วย/home/chroot/ld.so(และทำให้ symlink เป็นld-linux.so.2) และทำงานได้!

แต่ฉันคิดว่าทุกคนจะเห็นด้วยว่ามันเป็นกระบองขนาดใหญ่ที่จะเขียนเส้นทางของไบนารีใหม่ทุกตัวไปยังเส้นทางที่แน่นอนของระบบซ้อน

ไม่มีใครรู้วิธีที่สะอาดกว่าการใช้เส้นทางไลบรารีที่กำหนดเองรวมถึง ld-linux.so ที่กำหนดเอง?

คำตอบ:


12

พา ธ ไปยังตัวโหลดจะถูกรวบรวมเป็นไบนารี่เมื่อคุณค้นพบด้วยโปรแกรมแก้ไข hex ของคุณ คุณโชคดีจริงๆที่การแก้ไขไบนารีทำงานได้โดยตรงเพราะทั้งคู่/lib/ld-linux.so.2และ/home/chroot/ld.soมีความยาวเท่ากัน ความยาวของสตริงเหล่านั้นยังอยู่ในไบนารีและคุณสามารถทำให้เกิดปัญหาเล็กน้อยหากคุณแก้ไขสตริงโดยตรง

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


ไม่โชคดีฉันรู้ว่าฉันไม่ต้องการเปลี่ยนไบต์ใด ๆ ;-) แต่ patchelf ดูเหมือนสิ่งที่ฉันต้องการ นอกเหนือจากการไม่สามารถใช้เส้นทางสัมพัทธ์มันยังสามารถดูแล LD_LIBRARY_PATH ที่ฉันใช้เพื่อที่ฉันไม่จำเป็นต้องใช้กระดาษห่อ ฉันจะให้เครดิตคุณสำหรับคำตอบทันทีที่ฉันได้รับโอกาสทดสอบ
dataless

1
มันได้ผล! สิ่งนี้จะทำให้ฉันมีเส้นทางที่ดีไปข้างหน้าเพื่อผสมโปรแกรม libc ใหม่กับโปรแกรม libc เก่าบนเซิร์ฟเวอร์นี้ สำหรับผู้อ่านในอนาคตคำสั่งคือpatchelf --set-interpreter $JAVA/lib/ld-linux.so.2 --set-rpath $JAVA/lib:$JAVA/lib/i386:$JAVA/lib/i386/jli $JAVA/bin/javaที่ใด $ JAVA เป็นไดเรกทอรีของ JRE และที่ฉันรวบรวมไลบรารีที่ขึ้นต่อกันทั้งหมดและวางไว้ในlib/ไดเรกทอรีของ JRE
dataless

@dessess ดีฉันยังต้องการ LD_LIBRARY_PATH เพื่อแก้ปัญหา libjvm.so นี้เนื่องจาก libstdc ++. so.6: ไม่สามารถเปิดไฟล์วัตถุที่ใช้ร่วมกัน: ไม่มีไฟล์หรือไดเรกทอรี [root @ 97245bbe7cc1 tensorflow-java] #
Amos

@Amos เป็นเวลานาน ๆ แต่สำหรับกรณีของฉันฉันไม่ต้องการ LD_LIBRARY_PATH อีกต่อไปเพราะค่าเริ่มต้นมาจากไบนารีของจาวา แต่สังเกตส่วนที่ฉันบอกว่าฉันไปรอบ ๆ และพบ libs ทั้งหมดที่ใช้โดย java และคัดลอกลงใน java lib dir ฉันเคยldd $JAVA/bin/javaได้รับ ist นอกจากนี้ยังมี libc แบบไดนามิกบางอย่างที่คุณต้องการเช่น libnss.so
dataless
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.