我有一个二进制可执行文件,可以在我的 CentOS7 机器上运行。我scp
把它放到另一台 CentOS7 机器上,在尝试运行它时,出现权限被拒绝的情况。我使用的是 root 用户,该文件归 root 所有,我已启用所有权限(我放置它的目录也是如此):
# ls -lisa notserv
5112112 35292 -rwxrwxrwx 1 root root 36136938 Sep 14 08:23 notserv
# ls -lisad .
5112110 4 drwxrwxrwx 3 root root 4096 Sep 14 08:23 .
# ./notserv
-bash: ./notserv: Permission denied
SELinux 未启用:
# sestatus
SELinux status: disabled
这台机器由公司内的另一个团队维护,可能配置不同。我的问题是:还有什么其他原因会导致这种结果?
编辑
我正在使用的分区/tmp
似乎没有noexec
设置标志:
# pwd
/tmp
# mount | grep /tmp
/dev/md126p8 on /tmp type ext4 (rw,nosuid,nodev,noatime,data=ordered)
编辑2
有关文件和操作系统的更多信息:
# file notserv
notserv: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.4, BuildID[sha1]=7d5c9389a3c67ff50f9a16be3e47efd32f57e2c7, not stripped
# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
# uname -a
Linux oms0 3.10.0-1062.1.2.el7.x86_64 #1 SMP Mon Sep 30 14:19:46 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
至于ldd:
# ldd notserv
not a dynamic executable
但是,原始机器上写着:
# ldd notserv
linux-gate.so.1 => (0xf772f000)
libdl.so.2 => /lib/libdl.so.2 (0xf76fd000)
libpthread.so.0 => /lib/libpthread.so.0 (0xf76e2000)
libstdc++.so.6 => /lib/libstdc++.so.6 (0xf75f6000)
libm.so.6 => /lib/libm.so.6 (0xf75b4000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xf7598000)
libc.so.6 => /lib/libc.so.6 (0xf73cd000)
/lib/ld-linux.so.2 (0xf7730000)
答案1
您正尝试在 64 位系统上运行 32 位二进制文件,但您的系统没有安装 32 位 C 库(glibc)或任何其他 32 位库。
您可以安装必要的 32 位兼容库:
yum install glibc.i686 libstdc++.i686
现在您应该可以运行该程序了。
或者,您可以尝试从向您提供此二进制文件的来源获取 64 位二进制文件。
答案2
可能是您位于使用该noexec
选项挂载的目录中。
答案3
在我的例子中,在具有自己的 initramfs 的 arm64 嵌入式系统上,错误通过 2 个简单的命令完全修复:
# chmod a+x /lib/ld-2.31.so
# export LD_LIBRARY_PATH="/lib"
我怎么找到这个修复程序的?我真的不知道如何修复。在主机系统命令中,例如:
$ ~/x-tools/aarch64-unknown-linux-gnu/bin/aarch64-unknown-linux-gnu-ldd --root . <path to dynamically linked executable>
显示所有库都在 initramfs 映像上。然后我搜索了如何在嵌入式系统上运行“ldd”,并执行了:
$ file <..>/sysroot/usr/bin/ldd
<..>/sysroot/usr/bin/ldd: Bourne-Again shell script, ASCII text executable
哇,ldd 是 BASH 脚本,真的吗?我简直不敢相信,然后说道:
$ file /bin/ldd
/bin/ldd: Bourne-Again shell script, ASCII text executable
所以我看了这个脚本并发现了其他的惊喜:
$ /lib64/ld-linux-x86-64.so.2 --help
Usage: /lib64/ld-linux-x86-64.so.2 [OPTION]... EXECUTABLE-FILE [ARGS-FOR-PROGRAM...]
You have invoked 'ld.so', the program interpreter for dynamically-linked
ELF programs. Usually, the program interpreter is invoked automatically
when a dynamically-linked executable is started.
You may invoke the program interpreter program directly from the command
line to load and run an ELF executable file; this is like executing that
file itself, but always uses the program interpreter you invoked,
instead of the program interpreter specified in the executable file you
run. Invoking the program interpreter directly provides access to
additional diagnostics, and changing the dynamic linker behavior without
setting environment variables (which would be inherited by subprocesses).
--list list all dependencies and how they are resolved
--verify verify that given object really is a dynamically linked
object we can handle
--inhibit-cache Do not use /etc/ld.so.cache
--library-path PATH use given PATH instead of content of the environment
variable LD_LIBRARY_PATH
--glibc-hwcaps-prepend LIST
search glibc-hwcaps subdirectories in LIST
--glibc-hwcaps-mask LIST
only search built-in subdirectories if in LIST
--inhibit-rpath LIST ignore RUNPATH and RPATH information in object names
in LIST
--audit LIST use objects named in LIST as auditors
--preload LIST preload objects named in LIST
--argv0 STRING set argv[0] to STRING before running
--list-tunables list all tunables with minimum and maximum values
--list-diagnostics list diagnostics information
--help display this help and exit
--version output version information and exit
This program interpreter self-identifies as: /lib64/ld-linux-x86-64.so.2
Shared library search path:
(libraries located via /etc/ld.so.cache)
/lib/x86_64-linux-gnu (system search path)
/usr/lib/x86_64-linux-gnu (system search path)
/lib (system search path)
/usr/lib (system search path)
Subdirectories of glibc-hwcaps directories, in priority order:
x86-64-v4
x86-64-v3 (supported, searched)
x86-64-v2 (supported, searched)
Legacy HWCAP subdirectories under library search path directories:
haswell (AT_PLATFORM; supported, searched)
tls (supported, searched)
avx512_1
x86_64 (supported, searched)
因此 ld-library 不是简单的库,它是“解释器”,必须具有可执行权限。您可以轻松地使用带有“--list”参数的 ld.so 代替 ldd,如下所示:
$ /lib64/ld-linux-x86-64.so.2 --list /bin/bash
linux-vdso.so.1 (0x00007fff2b147000)
libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f023b940000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f023b75f000)
/lib64/ld-linux-x86-64.so.2 (0x00007f023bac5000)
并且export LD_LIBRARY_PATH="/lib"
需要知道查找库的路径。