Linux

使用 noexec 選項在文件系統上執行 bash 腳本或 ac 二進製文件

  • January 8, 2020

任何人都可以詳細解釋以下內容。假設我正在安裝一個帶有noexec以下選項的目錄:

mount -o noexec /dev/mapper/fedora-data /data

所以為了驗證這一點,我跑了mount | grep data

/dev/mapper/fedora-data on /data type ext4 (rw,noexec,relatime,seclabel,data=ordered)

現在/data我正在創建一個簡單的腳本hello_world,如下所示:

#!/bin/bash

echo "Hello World"
whoami

所以我使腳本可執行chmod u+x hello_world(但這對帶有noexec選項的文件系統沒有影響),我嘗試執行它:

# ./hello_world
-bash: ./hello_world: Permission denied

但是,準備bash文件會產生:

# bash hello_world
Hello World
root

所以我創建了一個簡單hello_world.c的內容如下:

#include <stdio.h>

int main()
{
   printf("Hello World\n");
   return 0;
}

編譯它使用 cc -o hello_world hello_world.c

現在執行:

# ./hello_world
-bash: ./hello_world: Permission denied

所以我嘗試使用

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

錯誤:

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

所以這當然是正確的,因為ldd返回以下內容:

ldd hello_world
ldd: warning: you do not have execution permission for `./hello_world'
   not a dynamic executable

在另一個noexec安裝選項不適用的系統上,我看到:

ldd hello_world
   linux-vdso.so.1 (0x00007ffc1c127000)
   libc.so.6 => /lib64/libc.so.6 (0x00007facd9d5a000)
   /lib64/ld-linux-x86-64.so.2 (0x00007facd9f3e000)

現在我的問題是:為什麼在帶有noexec選項的文件系統上執行 bash 腳本而不是c編譯程序?引擎蓋下發生了什麼?

兩種情況的情況是一樣的:直接執行文件,需要設置執行位,文件系統不能掛載noexec。但是這些東西並不能阻止任何東西讀取這些文件。

當 bash 腳本以 as 執行./hello_world並且文件不可執行(沒有 exec 權限位或文件系統上的 noexec )時,甚至不會檢查#!該行,因為系統甚至不會載入文件。該腳本永遠不會在相關意義上“執行”。

在這種情況下bash ./hello_world,noexec 文件系統選項只是普通的並不像您希望的那樣聰明。執行的bash命令是/bin/bash,並且/bin不在帶有noexec. 所以,它執行沒有問題。系統並不關心 bash(或 python 或 perl 或其他)是解釋器。它只是執行您給出的命令 ( /bin/bash) 並帶有恰好是一個文件的參數。對於 bash 或其他 shell,該文件包含要執行的命令列表,但現在我們“過去”了任何要檢查文件執行位的內容。該檢查不對以後發生的事情負責。

考慮這種情況:

$ cat hello_world | /bin/bash

……或者對於那些不喜歡毫無意義地使用貓的人:

$ /bin/bash < hello_world

#!當您嘗試將文件作為命令執行時,文件開頭的“shbang”序列只是一個很好的魔法,可以有效地做同樣的事情。您可能會發現這篇 LWN.net 文章很有幫助:程序如何執行

引用自:https://unix.stackexchange.com/questions/490402