Tại sao các hệ thống Unix / Linux không duyệt qua các thư mục cho đến khi chúng tìm thấy phiên bản bắt buộc của thư viện được liên kết?


17

Tôi có một tệp thực thi nhị phân có tên là "alpha" yêu cầu thư viện được liên kết (libz.so.1.2.7) được đặt tại /home/username/myproduct/lib/libz.so.1.2.7

Tôi xuất tương tự sang phiên bản đầu cuối của mình trước khi sinh ra tệp thực thi nhị phân của mình bằng cách thực hiện lệnh sau.

export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH

Bây giờ, khi tôi sinh ra một ứng dụng "bravo" khác yêu cầu cùng một thư viện nhưng phiên bản khác nhau, tức là (libz.so.1.2.8) có sẵn /lib/x86_64-linux-gnu/libz.so.1.2.8, hệ thống sẽ đưa ra lỗi sau.

version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)

Nếu tôi bỏ đặt LD_LIBRARY_PATH, "bravo" sẽ khởi động tốt. Tôi hiểu rằng hành vi trên là do LD_LIBRARY_PATHđược ưu tiên hơn các đường dẫn thư mục được xác định trong /etc/ld.so.confkhi tìm kiếm các thư viện được liên kết và do đó đã xảy ra lỗi ở trên. Tôi chỉ tò mò về lý do tại sao các nhà phát triển UNIX / LINUX không thiết kế HĐH để tìm kiếm các thư viện được liên kết trong các thư mục khác theo phân cấp nếu phiên bản đầu tiên của thư viện là phiên bản khác nhau.

Nói một cách đơn giản, các hệ thống UNIX / LINUX đi qua một tập các thư mục cho đến khi tìm thấy thư viện cần thiết. Nhưng tại sao nó không làm như vậy cho đến khi tìm thấy phiên bản dự kiến ​​thay vì chấp nhận phiên bản đầu tiên của thư viện không phân biệt phiên bản của nó?


Tôi không chắc lắm, nhưng tôi đoán để bảo mật. Cá nhân tôi không muốn phải lo lắng về một liên kết sym ở bất cứ đâu trên máy của mình
Joe

@Joe Nhiều thư viện có các liên kết tượng trưng cho chúng. libz.so.1là một liên kết đếnlibz.so.1.2.8
Nasir Riley

Câu trả lời:


28

Nhưng tại sao nó không làm như vậy cho đến khi tìm thấy phiên bản dự kiến ​​thay vì chấp nhận phiên bản đầu tiên của thư viện không phân biệt phiên bản của nó?

Nó làm, theo như nó biết. zlib.so.1.2.7zlib.so.1.2.8cả hai đều có một soname của zlib.so.1, vì vậy bạn alphabravonhị phân nói rằng họ cần zlib.so.1. Trình tải động tải thư viện phù hợp đầu tiên mà nó tìm thấy; không biết rằng phiên bản 1.2.8 cung cấp các biểu tượng bổ sung bravocần. (Đây là lý do tại sao các bản phân phối phải chịu khó chỉ định thông tin phụ thuộc bổ sung, chẳng hạn như zlib1g (>= 1.2.8)cho bravo.)

Bạn có thể nghĩ rằng việc này rất dễ sửa, nhưng không phải vì các tệp nhị phân và thư viện liệt kê các ký hiệu họ cần tách biệt với các thư viện họ cần, vì vậy trình tải không thể kiểm tra xem thư viện đã cho có cung cấp tất cả các ký hiệu không là cần thiết từ nó. Các biểu tượng có thể được cung cấp theo nhiều cách khác nhau và giới thiệu một liên kết giữa các biểu tượng và các thư viện cung cấp chúng có thể phá vỡ các nhị phân hiện có. Ngoài ra còn có thêm sự thú vị của sự thay thế biểu tượng để làm phức tạp mọi thứ (và khiến các nhà phát triển nhạy cảm với bảo mật xé tóc ra).

Một số thư viện cung cấp thông tin phiên bản cuối cùng được lưu trữ .gnu.version_r, với một liên kết đến thư viện cung cấp, sẽ giúp ích ở đây, nhưng libzkhông phải là một trong số đó.

(Đưa ra các sonames, tôi hy vọng alphanhị phân của bạn sẽ hoạt động tốt zlib.so.1.2.8.)


Và người ta cũng cần lưu ý rằng phiên bản thư viện kiểu GNU khác với phiên bản ngữ nghĩa (-ish) mà chúng ta quen thuộc nhất. Vì chúng có cùng số "hiện tại", 1, zlib.so.1.2.8 không nên cung cấp bất kỳ tính năng nào mà zlib.so.1.2.7 không có, do đó, nó không phải là vấn đề (từ góc độ ABI) tìm. Đó là vấn đề nên được coi là một lỗ hổng.
John Bollinger

4
@ John không, đảm bảo duy nhất là các thư viện có cùng soname tương thích ngược; các thư viện mới hơn có thể thêm các tính năng, họ không thể xóa bất kỳ hoặc thay đổi bất kỳ theo kiểu không tương thích ngược. Điều đó có nghĩa là, một nhị phân được xây dựng dựa trên zlib 1.2.7 sẽ hoạt động với hoặc bất kỳ zlib 1 mới hơn; nhưng một nhị phân được xây dựng dựa trên zlib 1.2.8 sẽ không nhất thiết phải hoạt động với zlib cũ hơn 1. (Và phiên bản ngữ nghĩa cho phép điều đó; nhưng xử lý soname không phải là phiên bản ngữ nghĩa.)
Stephen Kitt

1
Tôi đang nói cụ thể về các quy ước GNU, như tôi đã nói, và tôi đoán cụ thể về libtool . Không phải mọi dự án đều tuân theo quy ước đó, vì vậy có lẽ quá mạnh để gọi zlib là thiếu sót, nhưng mặt khác, ngay cả một cách giải thích phiên bản ngữ nghĩa của các số phiên bản thư viện liên quan cũng sẽ đi đến kết luận tương tự. Tương thích chuyển tiếp (nhị phân) trong các trường hợp như vậy không phải là một lời hứa cố hữu trong soname, nhưng đó một kỳ vọng hợp lý trong trường hợp này.
John Bollinger

1
Vâng, tôi hiểu rất rõ mối quan hệ giữa số CRA và SOVERSION, quay trở lại điểm ban đầu của tôi: tình huống được mô tả bởi OP dường như không phù hợp với cách sử dụng chính xác của sơ đồ CRA . Tránh các vấn đề như OP là một trong những mục tiêu chính của chương trình đó. Nếu zlib thêm giao diện nhị phân (phiên bản a) mới, thì số C của nó phải được tăng lên. Một vết sưng như vậy có thể dẫn đến một vết sưng soversion cũng là thứ yếu.
John Bollinger

2
@ John đúng, tôi nghi ngờ chúng tôi đang có thỏa thuận bạo lực và tôi đã hiểu nhầm quan điểm mà bạn đang đưa ra. dù sao zlibcũng không sử dụng libtool, ngoại trừ Darwin, nơi nó ar;-).
Stephen Kitt
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.