Kütüphane yükseltme sırasında uygulamaları koruyan bir mekanizma var mı?


10

Kullanıcı dinamik olarak bağlı bir uygulama üzerinde çalışıyorsa ve sistem yükseltiliyorsa, uygulamanın bozulmasını önleyen herhangi bir koruma mekanizması var mı?

Yoksa uygulamaya bağlı mı?


Kullanmanız gereken nasıl bir Linux kitap okuma hatırla ln -sfçünkü, kütüphaneler üzerinde takas zaman -fizin bunu hiç "kırık" olmadan yenisi ile sembolik bağın "yazma" mevcut hedef, (hiç bir eğer aksine rmardından a ln -s). Komuttan önce, library.so eski sürüme işaret etti, örn. library.so.4 ... komutundan sonra, sadece işaret library.so.5 yerine (ya da herneyse) - hiç olmadan değil , geçerli bir kütüphaneye işaret.
Baard Kopperud

Yanıtlar:


16

@Kusalananda tarafından belirtildiği gibi, genellikle eski dosyayı kaldırarak ve aynı ada sahip yeni bir dosya oluşturarak yükseltmeler yapılır. Bu aslında yeni bir inode ile yeni bir dosya oluşturacak ve sistemi eski dosyayı açık olduğu sürece serbest bırakacaktır.

Basitleştirilmiş bir örnek olarak,

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

mantıksal olarak yeni bir dosya oluşturur ve çalışıyor olsa bile catçalışır. Aynı şey kütüphaneler için de geçerli. (Yukarıdaki bir örnek, gerçek dünyada bir dosyayı yükseltmenin sağlam bir yolu değildir.)


Birisi aynı ada sahip yeni bir tane oluşturmak yerine ikili dosyayı yerinde değiştirmeye çalışabilir. Bu durumda, en azından Linux aslında kullanılan bir yürütülebilir dosyada değişiklik yapılmasını önler:

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

Ancak, bu dinamik olarak yüklenmiş kütüphanelerle çalışmıyor gibi görünüyor ...

libc.so.6Test için bir kopyasını yaptım ve kullanımdayken sıfırlarla doldurdum:

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

(Bu arada başka bir pencerede, foosegfault öncesi,)

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

Programın kodunu etkili bir şekilde çevrimiçi düzenlediğim için, programın kendisinin buna karşı yapabileceği gerçekten hiçbir şey yok.

(Bu muhtemelen sisteme bağlı olacaktır, Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3 üzerinde test ettim. Özellikle IIRC Windows sistemleri, kullanımdaki dosyaların değiştirilmesini önleme konusunda daha da agresiftir.)


Bu yüzden cevap, yükseltmelerin genellikle herhangi bir problemden kaçınacak şekilde yapıldığı ve bunun dosya sistemi içselleri tarafından yardımcı olduğu sanırım. Ancak (Linux'ta), aslında dinamik kütüphanelerin bozulmasına karşı herhangi bir güvence yok gibi görünüyor.


Yardımcı installprogram yaygın olarak bu tür şeyler için kullanılır. rmHedef dosyayı açıkça belirtmenize gerek yoktur . Ayrıca mevcut dosyanın izinlerini korur, yedekleme yapabilir, yeni bir mod ayarlayabilir vb. Örnek kullanım:install /new/version/of/cat /bin/cat
Patrick

Elbette. rm+ cpÖrnek olarak ifade edildi. Ayrıca, yeni dosyanın her ikisinin de bulunmadığı kısa bir pencereden kaçınmak için yeni dosyayı atomik olarak yerine koymak akıllıca olabilir. (GNU installbunu yapmamış gibi görünse de,
hmpf

2
Bu cevapta olan bir şeyi açıklığa kavuşturmak istiyorum: Unixes'te bir dosya açık ve kaldırılmışsa ( rm), o zaman henüz silinmez. Diskte mevcut olacak ve hala açık olan tüm işlemler tarafından okunabilecektir. Yalnızca sabit bağlantı sayısı sıfıra ulaştığında VE dosya açıkken yapılan önbellek sayısı sıfıra ulaştığında silinir.
ctrl-alt-delor

@Patrick: Yardımcı installprogram özellikle güvensiz! Hedef dosyayı atomik olarak değiştirmek yerine yerine yazar. mv(kaynak ve hedef aynı dizinde, kaynak genellikle geçici bir dosyadır) dosyaları yüklemenin tek güvenli yoludur.
R .. GitHub BUZA YARDIMCI DURDUR

1
@Patrick, stracesöylediğim gibi install, GNU coreutils'de hedef dosyanın bağlantısını kaldırıyor ve yerine yeni bir tane kopyalıyor. Bu, dosyanın kısmi olduğu kısa bir pencere olduğu anlamına gelir. Dosyayı yeniden adlandırma ile atomik olarak yerine koymaz.
ilkkachu

3

Dosyalar hala açıkken bağlantısı kaldırılırsa "düzgün bir şekilde silinmez". Kapatıldıklarında, kullandıkları disk alanı tekrar "boş" olarak kabul edilecektir. Bu, şu anda çalışan uygulamalar ve bunların paylaşılan kitaplıkları için de geçerlidir.

Başarısız olduğunu görebildiğim tek şey, bir programın dlopen()isteğe bağlı olarak paylaşılan bir kitaplığı yüklemek için kullandığı veya programın sözlükler, tema dosyaları veya aniden kaybolan diğer dosyalar gibi isteğe bağlı diğer dosyalara erişmesi gerektiğidir.

Örneklemek gerekirse: Başka bir kabuk oturumunun vimkurulumunu silerken vimbir kabuk oturumunda çalıştırmak, o anda çalışan vimoturumu "bozmaz" veya sonlandırmaz . Ancak, örneğin vimkurulumunda dosyaları açmayı gerektiren yazım denetimi gibi bazı şeyler başarısız olmaya başlayacaktır .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.