Dlaczego istnieją `/ lib` i` / lib64`, ale tylko `/ bin`?

27

W moim laptopie:

$ cat /etc/issue  
Ubuntu 18.04 LTS \n \l

Istnieją dwa różne foldery dla bibliotek x86i x86_64:

~$ ls -1 /  
bin
lib
lib64
sbin
...

Dlaczego dla plików binarnych istnieje tylko jeden katalog?

PS Interesuję się także Androidem, ale mam nadzieję, że odpowiedź powinna być taka sama.

Gluttton
źródło
1
Tylko w jednym? Widzę oba /bini /sbintam. Jakie jest pytanie? Czy pytasz o różnicę między /libi /lib64?
Kusalananda
2
@Kusalananda, mam na myśli, że nie ma niezależnego folderu dla x86_64(ani dla /binnie dla /sbin).
Gluttton
7
IMO OP chce wiedzieć, dlaczego nie ma /bin64.
Arkadiusz Drabczyk
W przybliżeniu jedna aplikacja, która korzysta zarówno z wersji 32-bitowej, jak i 64-bitowej (WINE), omija tę funkcję, mając pliki binarne o różnych nazwach ( wine*32i wine*64).
Ignacio Vazquez-Abrams
1
@ IgnacioVazquez-Abrams: należy również powiedzieć, że łączysz binaria z bibliotekami, a nie odwrotnie. Pliki binarne nie muszą być partycjonowane według 32/64-bitów.
smci

Odpowiedzi:

25

Po pierwsze, dlaczego istnieją osobne /libi /lib64:

Filesystem Hierarchy Standard wspomina, że oddzielne /libi /lib64istnieją, ponieważ:

10.1 W systemach, które obsługują więcej niż jeden format binarny wymagający osobnych bibliotek, może istnieć jeden lub więcej wariantów katalogu / lib. (...) Jest to powszechnie używane do obsługi 64-bitowej lub 32-bitowej w systemach obsługujących wiele formatów binarnych, ale wymagających bibliotek o tej samej nazwie. W takim przypadku / lib32 i / lib64 mogą być katalogami bibliotek, a / lib dowiązaniem symbolicznym do jednego z nich.

Na przykład w moim Slackware 14.2 są /libi /lib64 katalogi dla bibliotek 32-bitowych i 64-bitowych, chociaż /libnie jest tak dowiązaniem symbolicznym, jak sugerowałby fragment kodu FHS:

$ ls -l /lib/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11  2016 /lib/libc.so.6 -> libc-2.23.so
$ ls -l /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Aug 11  2016 /lib64/libc.so.6 -> libc-2.23.so

Istnieją dwie libc.so.6biblioteki w /libi /lib64.

Każdy dynamicznie zbudowany ELF binarny zawiera Hardcoded ścieżkę do interpretera, w tym przypadku albo /lib/ld-linux.so.2albo /lib64/ld-linux-x86-64.so.2:

$ file main
main: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, not stripped
$ readelf  -a main  | grep 'Requesting program interpreter'
      [Requesting program interpreter: /lib/ld-linux.so.2]

$ file ./main64
./main64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, not stripped
$ readelf  -a main64  | grep 'Requesting program interpreter'
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]

Tłumacz ma za zadanie załadować niezbędne biblioteki współdzielone. Możesz zapytać interpretera GNU, jakie biblioteki by załadował, nawet bez uruchamiania pliku binarnego LD_TRACE_LOADED_OBJECTS=1lub lddopakowania:

$ LD_TRACE_LOADED_OBJECTS=1 ./main
        linux-gate.so.1 (0xf77a9000)
        libc.so.6 => /lib/libc.so.6 (0xf760e000)
        /lib/ld-linux.so.2 (0xf77aa000)
$ LD_TRACE_LOADED_OBJECTS=1 ./main64
        linux-vdso.so.1 (0x00007ffd535b3000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f56830b3000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f568347c000)

Jak widać, dany tłumacz dokładnie wie, gdzie szukać bibliotek - wersja 32-bitowa szuka bibliotek w, /liba wersja 64-bitowa szuka bibliotek /lib64.

Standard FHS mówi, co następuje /bin:

/ bin zawiera polecenia, które mogą być używane zarówno przez administratora systemu, jak i przez użytkowników, ale są wymagane, gdy nie podłączono żadnego innego systemu plików (np. w trybie pojedynczego użytkownika). Może także zawierać polecenia używane pośrednio przez skrypty.

IMO jest powodem, dla którego nie ma oddzielnych plików /bini /bin64jest to, że gdybyśmy mieli plik o tej samej nazwie w obu tych katalogach, nie moglibyśmy wywołać jednego z nich pośrednio, ponieważ musielibyśmy umieścić /binlub /bin64najpierw $PATH.

Zauważ jednak, że powyższe to tylko konwencja - jądro Linuksa tak naprawdę nie dba o to, czy masz oddzielne /bini /bin64. Jeśli chcesz, możesz je utworzyć i odpowiednio skonfigurować system.

Wspomniałeś także o Androidzie - pamiętaj, że oprócz uruchamiania zmodyfikowanego jądra Linuksa, nie ma to nic wspólnego z systemami GNU, takimi jak Ubuntu - bez glibc, bez bash (domyślnie można go oczywiście skompilować i wdrożyć ręcznie), a także strukturę katalogów jest zupełnie inny.

Arkadiusz Drabczyk
źródło
Twoje ls -lprzykłady nie są szczególnie niemądre. Co by być przydatna jest wyjście ls -l /lib /lib64, które prawdopodobnie wskazują, że /libsama jest dowiązaniem symbolicznym.
Chrylis
Miałeś na myśli ls -ld, i nie, /libto nie jest dowiązanie symboliczne w moim Slackware 14.2systemie.
Arkadiusz Drabczyk
Biblioteki mają różne sumy md5: dfd029d25c58831bc5db671aec99a36f /lib64/libc.so.6, 987e7b736f316cc8da87ca2f38dae93e /lib/libc.so.6.
Arkadiusz Drabczyk
2
W takim przypadku pokazanie dowiązań symbolicznych w katalogu nie łączy się z cytatem.
Chrylis
1
LD_TRACE_LOADED_OBJECTS = 1 jest przestarzały z powodu luki bezpieczeństwa i ldd już go nie używa. Powód: do przejęcia systemów wykorzystano ldd / path / to / malware-static-binary, ponieważ sysadmini oczekiwali, że ldd będzie patrzeć tylko na plik binarny, ale go nie uruchamia. Ponadto sprawdzanie statyczności lub jej brak jest niewystarczające, ponieważ plik binarny można skonstruować tak, aby zamiast tego używał złośliwego modułu ładującego.
Joshua
22

Powodem jest to, że katalogi lib / lib64 mogą zawierać pliki o takich samych nazwach, ponieważ są to biblioteki współużytkowane przez różne programy. Umieszczenie ich w osobnych katalogach rozwiązuje konflikt. (Zazwyczaj ...) nie ma dobrego powodu do dystrybucji plików wykonywalnych o tej samej nazwie w tym samym systemie, które są 32/64-bitowe, ale ponieważ może istnieć mieszanka plików wykonywalnych, należy udostępnić biblioteki współdzielone.

Thomas Dickey
źródło