Có một cơ chế bảo vệ các ứng dụng trong quá trình nâng cấp thư viện?


10

Nếu người dùng làm việc trên một ứng dụng được liên kết động và hệ thống đang được nâng cấp, có cơ chế bảo vệ nào ngăn chặn tham nhũng của ứng dụng không?

Hoặc là nó lên đến ứng dụng?


Hãy nhớ đọc một cuốn sách Linux về cách bạn nên sử dụng ln -sfkhi trao đổi thư viện, bởi vì điều đó -fcho phép bạn "ghi đè" đích đến hiện tại của liên kết tượng trưng với một liên kết mới, mà không bao giờ bị "phá vỡ" (không giống như bạn đã làm rmtheo a ln -s). Vì vậy, trước lệnh, library.so đã chỉ vào phiên bản cũ, vd. library.so.4 ... sau lệnh, nó chỉ đơn giản chỉ vào library.so.5 (hoặc bất cứ điều gì) thay vào đó - mà không bao giờ không trỏ đến một thư viện hợp lệ.
Baard Kopperud

Câu trả lời:


16

Như @Kusalananda đã đề cập, thông thường việc nâng cấp được thực hiện bằng cách xóa tệp cũ và tạo tệp mới có cùng tên. Điều này thực sự sẽ tạo một tệp mới với một nút mới, để hệ thống tự do sử dụng tệp cũ miễn là nó được mở.

Như một ví dụ đơn giản, những thứ như

rm /bin/cat
cp /new/version/of/cat /bin/cat

sẽ tạo một tệp mới logic và hoạt động ngay cả khi catcó thể đang chạy. Các thư viện cũng vậy. (Trên đây là một ví dụ, không phải là một cách mạnh mẽ để nâng cấp tệp trong thế giới thực.)


Ai đó có thể cố gắng thay đổi vị trí nhị phân thay vì tạo một cái mới có cùng tên. Trong trường hợp này, ít nhất Linux thực sự ngăn chặn việc thực hiện các thay đổi đối với một tệp thực thi đang được sử dụng:

window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy

Tuy nhiên, điều này dường như không hoạt động với các thư viện được tải động ...

Tôi đã tạo một bản sao libc.so.6để thử nghiệm và điền vào đó các số 0 trong khi nó đang được sử dụng:

window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
    linux-vdso.so.1 (0x00007ffcfaf30000)
    libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)

window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo

Segmentation fault

(Trong khi đó ở một cửa sổ khác, sau foo, trước segfault)

window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000

Thực sự không có gì chương trình có thể làm được để chống lại điều này, vì tôi đã chỉnh sửa mã trực tuyến một cách hiệu quả.

(Điều này có thể phụ thuộc vào hệ thống


Vì vậy, tôi đoán câu trả lời là việc nâng cấp thường được thực hiện theo cách tránh mọi vấn đề và điều này được trợ giúp bởi các bên trong hệ thống tập tin. Nhưng (trên Linux) dường như không có bất kỳ biện pháp bảo vệ nào chống lại các thư viện động thực sự làm hỏng.


Các installtiện ích thường được sử dụng cho những thứ như thế này. Bạn không cần phải dứt khoát rmcác tập tin đích. Thêm vào đó, nó bảo vệ các quyền của tệp hiện có, có thể tạo bản sao lưu, thiết lập chế độ mới, v.v ... Cách sử dụng ví dụ:install /new/version/of/cat /bin/cat
Patrick

Chắc chắn rồi. Dấu rm+ cpcó nghĩa là một ví dụ. Cũng có thể là thông minh khi đặt tệp mới vào vị trí nguyên tử bằng cách đổi tên, tránh một cửa sổ ngắn không có phiên bản nào. (Mặc dù GNU installthậm chí dường như không làm điều đó, hmpf.)
ilkkachu

2
Tôi muốn làm rõ một cái gì đó trong câu trả lời này: Trong Unix nếu một tệp được mở và bị xóa ( rm), thì nó vẫn chưa bị xóa. Nó sẽ tồn tại trên đĩa và vẫn có thể được đọc bởi tất cả các quá trình mở nó. Nó sẽ chỉ bị xóa khi số lượng liên kết cứng của nó đạt đến 0 VÀ số lượng điều kiện tiên quyết với tệp được mở đạt đến không.
ctrl-alt-delor

@Patrick: installTiện ích đặc biệt không an toàn! Nó ghi đè lên tệp đích thay vì thay thế nguyên tử. mv(với nguồn và mệnh trong cùng một thư mục, nguồn thường là tệp tạm thời) là cách an toàn duy nhất để cài đặt tệp.
R .. GitHub DỪNG GIÚP ICE

1
@Patrick theo như tôi stracenói, installtrong GNU coreutils hủy liên kết tệp đích và sau đó sao chép một tệp mới vào vị trí của nó. Điều đó có nghĩa là có một cửa sổ ngắn trong đó tệp là một phần. Nó không đặt tập tin nguyên bản vào vị trí đổi tên.
ilkkachu

3

Các tệp sẽ không được "xóa đúng" nếu chúng không được liên kết trong khi chúng vẫn được mở. Khi chúng được đóng lại, không gian đĩa mà chúng sử dụng sẽ được coi là "miễn phí" một lần nữa. Điều này áp dụng cho các ứng dụng hiện đang chạy và thư viện chia sẻ của họ là tốt.

Điều duy nhất tôi có thể thấy thất bại là nếu một chương trình được sử dụng dlopen()để tải thư viện dùng chung theo yêu cầu hoặc nếu chương trình phải truy cập các tệp khác theo yêu cầu như từ điển, tệp chủ đề hoặc các tệp khác đột nhiên biến mất.

Để minh họa: Chạy vimtrong một phiên shell trong khi xóa cài đặt vimtrong phiên shell khác sẽ không "hỏng" hoặc chấm dứt phiên hiện đang chạy vim. Nhưng một số thứ sẽ bắt đầu thất bại, chẳng hạn như kiểm tra chính tả, yêu cầu vimmở tệp trong cài đặt của nó.

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.