为什么 Bash 的源代码不需要执行位?

为什么 Bash 的源代码不需要执行位?

使用 Bashsource可以在没有设置执行位的情况下执行脚本。这是有记录的和预期的行为,但这不是违反执行位的使用吗?

我知道,这source不会创建子外壳。

答案1

source或同等但标准的.不执行脚本,但是脚本文件中的命令,然后在当前 shell 环境中逐行执行它们。

没有什么反对使用执行位,因为 shell 只需要读取文件内容的权限。

仅当您执行时才需要执行位跑步剧本。这里 shell 将fork()新进程然后使用execve()函数从脚本创建新的进程映像,该映像需要是常规的可执行文件。

答案2

Bash 是一个解释器;它接受输入并做任何它想做的事。它不需要注意可执行位。事实上,Bash 是可移植的,并且可以在没有任何可执行位概念的操作系统和文件系统上运行。

关心可执行位的是操作系统内核。exec例如,当 Linux 内核执行操作时,它会检查文件系统是否未使用noexec选项挂载,它会检查程序文件的可执行位,并强制执行安全模块(例如 SELinux 或 AppArmor)施加的任何要求。

请注意,可执行位是一种相当随意的控制。例如,在 Linux x86-64 系统上,您可以通过以下方式绕过内核对可执行位的验证/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2作为解释器显式调用:

cp /bin/ls /tmp/
chmod -x /tmp/ls
/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2 /tmp/ls

这有点类似于在 Bash 中获取 Bash 源代码,只不过它ld.so是解释器,并且它执行的代码是 ELF 格式的机器代码。

答案3

nonsetuid 和 nonsetguid 文件上的可执行位(与其他位不同)并不是一种安全机制。任何你能读取的东西,你都可以间接运行,Linux 会让你间接读取任何你能运行但不能直接读取的东西(这应该足以在非 set(g)uid x 位是一个概念上打一个洞)安全措施)。

这更方便:如果设置了该位,则让系统直接为我运行它,否则我需要间接执行它(bash the_script;或某些黑客获取无读权限可执行文件的内存映像)。

如果您打算内源化并执行您的非资源,您可以设置它以方便起见。

然而,显然,许多共享库实现者都同意您的想法,因此,许多系统确实需要将共享库(本质上是 shell insourcables 的本机等效项)标记为可执行才能使用。看为什么共享库可执行?

答案4

对于操作系统而言,包含 shell 脚本的文件只是数据。如果将此类数据文件的名称传递给命令source或在命令行上将其传递给 bash shell 的调用,则操作系统看到的只是一个恰好与包含数据的文件名一致的字符串。

在这种情况下,执行位有何相关性?

相关内容