Như đã đề cập trong Tại sao một gói phần mềm chỉ chạy tốt ngay cả khi nó đang được nâng cấp? , khóa được đặt trên inode không phải trên tên tệp. Khi bạn tải và thực thi nhị phân, tệp được đánh dấu là bận - đó là lý do tại sao bạn gặp lỗi ETXTBSY (tệp bận) khi bạn cố gắng ghi vào tệp.
Bây giờ, đối với các thư viện dùng chung, nó hơi khác một chút: các thư viện được ánh xạ bộ nhớ vào không gian địa chỉ của tiến trình mmap()
. Mặc dù MAP_DENYWRITE
có thể được chỉ định, ít nhất Glibc trên Linux âm thầm bỏ qua nó (theo trang man, vui lòng kiểm tra các nguồn) - kiểm tra chủ đề này . Do đó, bạn thực sự được phép ghi tệp và, vì nó được ánh xạ bộ nhớ, mọi thay đổi sẽ hiển thị gần như ngay lập tức - điều đó có nghĩa là nếu bạn cố gắng hết sức, bạn có thể quản lý để gạch máy của mình bằng cách ghi đè lên thư viện.
Do đó, cách chính xác để cập nhật là:
xóa tệp, loại bỏ tham chiếu đến dữ liệu khỏi hệ thống tệp, do đó không thể truy cập được đối với bất kỳ ứng dụng mới sinh nào có thể muốn sử dụng, trong khi vẫn giữ dữ liệu có thể truy cập được cho bất kỳ ai đã mở (hoặc ánh xạ) ;
tạo một tập tin mới với nội dung được cập nhật.
Các quy trình mới được tạo sẽ sử dụng các nội dung được cập nhật, các ứng dụng đang chạy sẽ truy cập phiên bản cũ. Đây là những gì bất kỳ tiện ích quản lý gói sane làm. Lưu ý rằng nó không hoàn toàn không có bất kỳ nguy hiểm nào - ví dụ: các ứng dụng tải mã động (sử dụng dlsym()
và bạn bè) sẽ gặp rắc rối nếu API của thư viện thay đổi âm thầm.
Nếu bạn muốn ở bên thực sự, thực sự an toàn, hãy tắt hệ thống, gắn hệ thống tệp từ một phiên bản hệ điều hành khác, cập nhật và đưa hệ thống cập nhật lại.
.so
tệp bằng cách sử dụngldd filename.so
để kiểm tra các phụ thuộc