ShlibvisibilityChecker เป็นเครื่องมือขนาดเล็กที่ค้นหาสัญลักษณ์ภายในที่ส่งออกจากไลบรารีที่ใช้ร่วมกันโดยไม่จำเป็น สัญลักษณ์ดังกล่าวไม่เป็นที่พึงปรารถนาเพราะเป็นสาเหตุ
--gc-sections ) ShlibvisibilityChecker เปรียบเทียบ APIs ที่ประกาศในส่วนหัวสาธารณะกับ API ที่ส่งออกจากห้องสมุดที่ใช้ร่วมกันและเตือนเกี่ยวกับความคลาดเคลื่อน ในกรณีส่วนใหญ่สัญลักษณ์ดังกล่าวเป็นสัญลักษณ์ไลบรารีภายในซึ่งควรซ่อนอยู่ (ในกรณีที่หายากเหล่านี้เป็นสัญลักษณ์ภายในซึ่งใช้โดยไลบรารีอื่นหรือปฏิบัติการอื่น ๆ ในแพ็คเกจเดียวกันและ shlibvischeck-debian พยายามอย่างหนักที่จะไม่รายงานกรณีดังกล่าว)
ความคลาดเคลื่อนดังกล่าวควรได้รับการแก้ไขโดยแพ็คเกจการคอมไพล์ใหม่ด้วย -fvisibility=hidden (ดูรายละเอียดที่นี่) การแก้ไขทั่วไปสำหรับโครงการ AutoConf ทั่วไปสามารถพบได้ที่นี่
ShlibvisibilityChecker ไม่ ได้หมายถึงความแม่นยำ 100% แต่ให้ความช่วยเหลือในการค้นหาแพ็คเกจซึ่งอาจเป็นประโยชน์ต่อคำอธิบายประกอบการมองเห็นมากที่สุด (และเข้าใจว่าสถานการณ์ที่ไม่ดีเกิดขึ้นในการมองเห็นที่ทันสมัย)
ในการตรวจสอบแพ็คเกจดิบเช่นส่วนหัวและ libs ที่ใช้ร่วมกันรวบรวมแหล่งที่มาและอินเทอร์เฟซไบนารีและเปรียบเทียบ:
$ bin/read_header_api --only-args /usr/include/xcb/* > api.txt
$ ./read_binary_api --permissive /usr/lib/x86_64-linux-gnu/libxcb*.so > abi.txt
$ vimdiff api.txt abi.txt # Or `comm -13 api.txt abi.txt'
สถานการณ์ที่มีประโยชน์อีกประการหนึ่งคือการค้นหาสัญลักษณ์ที่ส่งออกจากห้องสมุดที่ใช้ร่วมกันของแพ็คเกจ Debian แต่ไม่ได้ประกาศในส่วนหัวของมัน เครื่องมือหลักสำหรับสิ่งนี้คือสคริปต์ shlibvischeck-debian
หากต้องการใช้กับแพ็คเกจให้เรียกใช้
$ shlibvischeck-debian libacl1
The following exported symbols in package 'libacl1' are private:
__acl_extended_file
__acl_from_xattr
__acl_to_xattr
__bss_start
_edata
_end
_fini
_init
closed
head
high_water_alloc
next_line
num_dir_handles
walk_tree
หากต้องการข้ามสัญลักษณ์ autogenerated เช่น _init หรือ _edata (เกิดจากสคริปต์ LD Linker และไฟล์เริ่มต้น LIBGCC) เพิ่ม --permissive
นอกจากนี้คุณยังสามารถตรวจสอบปัญหาการมองเห็นในชุดส่วนหัวและห้องสมุดโดยพลการ:
$ shlibvischeck-common --permissive --cflags="-I/usr/include -I$AUDIT_INSTALL/include -I/usr/lib/llvm-5.0/lib/clang/5.0.0/include" $AUDIT_INSTALL/include/*.h $AUDIT_INSTALL/lib/*.so*
ข้อกำหนดเบื้องต้นของการสร้างเวลาคือ python3 (โมดูล setuptools ), clang , llvm , libclang-dev , g++ และ make การพึ่งพาเวลาทำงานคือ python3 (โมดูล python-magic ), pkg-config และ aptitude หากต้องการติดตั้งทุกอย่างบน Ubuntu Run
$ sudo apt-get install python3 clang llvm libclang-dev g++ make pkg-config aptitude
$ sudo python3 -mensurepip
$ sudo pip3 install setuptools python-magic
(คุณยังสามารถใช้สคริปต์ scripts/install-deps.sh )
คุณต้องเปิดใช้งานการเข้าถึงแพ็คเกจแหล่งข้อมูล Ubuntu ผ่านทางผ่าน
$ sudo sed -Ei 's/^# *deb-src /deb-src /' /etc/apt/sources.list
$ sudo apt-get update
ส่วนประกอบ Python และไบนารีถูกสร้างแยกต่างหาก:
$ make clean all && make install
$ ./setup.py build && pip3 install .
ในระหว่างการวิเคราะห์ shlibvischeck-debian ติดตั้งแพ็คเกจ Debian ใหม่ดังนั้นจึงแนะนำให้เรียกใช้ภายใต้ Chroot หรือใน VM มีคำแนะนำมากมายเกี่ยวกับการตั้งค่า chroot เช่นนี้
รายการแพ็คเกจสำหรับการวิเคราะห์สามารถรับได้จากการจัดอันดับ Debian:
$ curl https://popcon.debian.org/by_vote | awk '/^[0-9]+ +lib/{print $2}' > by_vote
$ shlibvischeck-debian $(head -500 by_vote | tr 'n' ' ')
เมื่อคุณพบแพ็คเกจที่มีปัญหาคุณสามารถแก้ไขได้โดยการ จำกัด การมองเห็นสัญลักษณ์ภายใน วิธีที่ดีที่สุดในการควบคุมการมองเห็นสัญลักษณ์ในแพ็คเกจคือ
-fvisibility=hidden ใน CFLAGS ในโครงการ buildscripts ( Makefile.in หรือ CMakeLists.txt )__attribute__((visibility("default")))ดูการแก้ไขใน Libcaca
ในขณะนี้เครื่องมือทำงานเฉพาะในระบบที่ใช้ Debian (เช่น Ubuntu) สิ่งนี้น่าจะดีเนื่องจาก buildscripts เหมือนกันในทุก distros ดังนั้นการตรวจจับปัญหาเกี่ยวกับ Ubuntu จะให้บริการคนอื่นเช่นกัน
ปัญหาการออกแบบที่สำคัญคือเครื่องมือไม่สามารถตรวจจับสัญลักษณ์ที่ใช้ทางอ้อมได้เช่นไม่ผ่าน API แต่ผ่าน dlsym หรือการประกาศต้นแบบต้นแบบนอกหัวอย่างชัดเจนในไฟล์ต้นฉบับ สิ่งนี้เกิดขึ้นในปลั๊กอินหรือ shlibs ที่เชื่อมต่อกันอย่างแน่นหนาภายในโครงการเดียวกัน กรณีดังกล่าวหวังว่าจะหายาก
ShlibvisibilityChecker เป็นเครื่องมือฮิวริสติกดังนั้นจึงไม่สามารถวิเคราะห์แพ็คเกจทั้งหมดได้ อัตราความสำเร็จในปัจจุบันอยู่ที่ประมาณ 60% เหตุผลสำคัญสำหรับข้อผิดพลาดคือ
libatasmart ล้มเหลวในการรวม stddef.h และ tdb ล้มเหลวในการรวม sys/types.h )lzma/container.h )dpkg/macros.h ต้องการ LIBDPKG_VOLATILE_API )libverto-dev ใช้ส่วนหัวของ GLIB แต่ไม่ได้ประกาศสิ่งนี้)ปัญหาอื่น ๆ :
เครื่องมือพบแพ็คเกจจำนวนมากที่ขาดคำอธิบายประกอบการมองเห็น (ในทางปฏิบัติทุกแพ็คเกจที่สองมีการส่งออกปลอม) นี่คือบางส่วนที่ฉันพยายามแก้ไข:
แพ็คเกจมุมมองเพิ่มเติม (จาก Debian Top-100): Libpopt1, libgpg-error0, libxml2, libwrap0, libpcre3, libkeyutils1, libedit2, liblcms2-2