GNU/Linux >> Znalost Linux >  >> Linux

Spuštění bash skriptu nebo binárního c na souborovém systému s možností noexec

To, co se děje v obou případech, je stejné:pro přímé spuštění souboru je třeba nastavit spouštěcí bit a souborový systém nelze připojit noexec. Ale tyto věci nic nebrání čtení tyto soubory.

Když je bash skript spuštěn jako ./hello_world a soubor není spustitelný (buď žádný bit oprávnění exec, nebo noexec v souborovém systému), #! řádek není ani zaškrtnutý , protože systém ani nenačte soubor. Skript není nikdy „spuštěn“ v příslušném smyslu.

V případě bash ./hello_world , no, volba souborového systému noexec prostě není tak chytrá, jak byste chtěli. bash příkaz, který se spustí, je /bin/bash a /bin není na souborovém systému s noexec . Takže to běží bez problémů. Systému je jedno, že bash (nebo python nebo perl nebo cokoli jiného) je interpret. Pouze spustí příkaz, který jste zadali (/bin/bash ) s argumentem, který je náhodou soubor. V případě bash nebo jiného shellu tento soubor obsahuje seznam příkazů k provedení, ale nyní jsme „minuli“ vše, co bude kontrolovat bity spouštění souboru. Tato kontrola nezodpovídá za to, co se stane později.

Zvažte tento případ:

$ cat hello_world | /bin/bash

… nebo pro ty, kteří nemají rádi nesmyslné používání kočky:

$ /bin/bash < hello_world

"shbang" #! sekvence na začátku souboru je jen pěkné kouzlo pro efektivní provedení stejné věci, když se pokusíte spustit soubor jako příkaz. Tento článek na LWN.net vám může pomoci:Jak se spouštějí programy.


Předchozí odpovědi vysvětlují, proč noexec nastavení nebrání spuštění skriptu při interpretaci (ve vašem případě /bin/bash ) se explicitně volá z příkazového řádku. Ale pokud by to bylo všechno, tento příkaz by fungoval také:

/lib64/ld-linux-x86-64.so.2 hello_world

A jak jsi poznamenal, nefunguje to. To proto, že noexec má i jiný efekt. Jádro nepovolí soubory mapované do paměti z tohoto souborového systému s PROT_EXEC povoleno.

Soubory mapované do paměti se používají ve více scénářích. Dva nejběžnější scénáře jsou pro spustitelné soubory a knihovny. Když je program spuštěn pomocí execve systémové volání, jádro interně vytvoří mapování paměti pro linker a spustitelný soubor. Jakékoli další potřebné knihovny jsou paměti mapované linkerem prostřednictvím mmap systémové volání s PROT_EXEC povoleno. Pokud jste se pokusili použít knihovnu ze souborového systému s noexec jádro by odmítlo provést mmap zavolejte.

Když jste zavolali /lib64/ld-linux-x86-64.so.2 hello_world execve systémové volání vytvoří pouze mapování paměti pro linker a linker otevře hello_world spustitelný a pokusit se vytvořit mapování paměti v podstatě stejným způsobem, jakým by to bylo pro knihovnu. A to je bod, ve kterém jádro odmítá provést mmap zavolejte a dostanete chybu:

./hello_world: error while loading shared libraries: ./hello_world: failed to map segment from shared object: Operation not permitted

noexec nastavení stále umožňuje mapování paměti bez povolení ke spuštění (jak se někdy používá u datových souborů) a také umožňuje normální čtení souborů, proto bash hello_world pracoval pro vás.


Provedení příkazu tímto způsobem:

bash hello_world

uděláte bash číst ze souboru hello_world (což není zakázáno).

V ostatních případech se OS pokusí spustit tento soubor hello_world a selže kvůli noexec vlajka


Linux
  1. Může být Bash skript připojen k souboru?

  2. Hromadné přejmenování souboru Bash pomocí čítače?

  3. Bash Script:Zkontrolujte, zda je soubor textovým souborem?

  1. Nelze zastavit Bash skript pomocí Ctrl+c?

  2. Spuštění plochého binárního souboru pod Linuxem

  3. Jak zvýraznit Bash skripty ve Vimu?

  1. Změna hesla systému Linux ve skriptu bash

  2. Bash skript:špatný interpret

  3. základní jméno s mezerami ve skriptu bash?