Linux 系统 | /bin/chmod 权限被误设为 000

注:本文为 "Linux 系统 /bin/chmod 权限被误设为 000 恢复方案 " 相关合辑。

英文引文,机翻未校。

中文引文,略作重排。

如有内容异常,请看原文。


Linux系统中 /bin/chmod 权限被误设为 000 的恢复

一、问题背景与原理

1.1 问题现象

当使用 chmod 000 /bin/chmod 将 chmod 命令本身的权限清空后,即使是 root 用户也无法直接执行该命令,具体现象如下:

bash 复制代码
[root@localhost ~]# ll /bin/chmod
----------. 1 root root 48712 Oct 15 2014 /bin/chmod
[root@localhost ~]# chmod 755 /bin/chmod
-bash: /bin/chmod: Permission denied

补充:误操作 chmod 222 /bin/chmod(仅读写权限,无执行权限)、chmod -R 000 /bin(批量清空/bin目录权限),会出现类似无法执行 chmod 的问题,本文方法均适用。

1.2 原理

Linux 内核对文件执行权限的检查分为两个阶段,二者相互独立,root 用户仅能豁免其中一个阶段的限制,这是权限误设后无法直接执行 chmod 的原因:

  1. 访问控制检查 :验证进程对文件的读/写/执行权限。root 用户(UID = 0)凭借 CAP_DAC_OVERRIDECAP_DAC_READ_SEARCH capability,在此阶段被内核豁免,可无视文件的读、写权限限制。
  2. 执行权限位检查 :验证文件模式位中是否存在执行位(S_IXUSRS_IXGRPS_IXOTH)。此检查对所有用户均生效,包括 root 用户,这也是 chmod 000 后 root 仍无法执行该命令的关键原因。
    补充说明:root 用户不受文件读权限限制,因此可以读取 000 权限的文件内容,这为后续部分恢复方法(如复制文件内容、编译小程序)提供了基础。
    所有恢复方法的逻辑一致:绕过 (/bin/chmod) 自身的执行权限限制,直接修改其权限位,或调用内核 chmod() 系统调用完成权限恢复。

二、恢复方法

整合两篇文档的有效方法,去除重复项、补充细节,按"原生无依赖→常用简洁→应急备用→极端场景"排序,每种方法均明确原理、操作、适用条件及注意事项,兼顾易用性与专业性。

2.1 动态链接加载器法(无依赖)

原理:动态链接的可执行文件实际由解释器(动态链接器)加载执行,直接调用加载器可绕过文件本身的执行权限检查,仅要求加载器自身具备执行权限;root 权限下可忽略文件读权限限制,无需依赖正常的 chmod 命令。

格式:加载器 + 被加载文件 + 被加载文件要执行的操作参数(权限值 + 操作目标文件)

操作命令(适配不同系统架构与C库):

  1. 64 位系统(glibc,如 Ubuntu、CentOS):

    bash 复制代码
    /lib64/ld-linux-x86-64.so.2 /bin/chmod 755 /bin/chmod
  2. 32 位系统(glibc):

    bash 复制代码
    /lib/ld-linux.so.2 /bin/chmod 755 /bin/chmod
  3. musl C 库系统(如 Alpine):

    bash 复制代码
    /lib/ld-musl-x86_64.so.1 /bin/chmod 755 /bin/chmod
  4. Debian/Ubuntu 系统可简化为:

    bash 复制代码
    sudo ld.so /bin/chmod 755 /bin/chmod

适用条件:

  • 系统使用 GNU C Library(glibc)或 musl 等主流 C 库;
  • (/bin/chmod) 为动态链接 ELF 文件(静态链接不适用);
  • 动态链接器本身权限正常(未被设为 000)。
    注意:若动态链接器本身也被设为 000,系统所有动态链接程序均无法执行,此时需使用 Live CD 修复。

2.2 BusyBox 法(操作简洁)

原理:BusyBox 是一个集成多种工具的精简工具集,多数 Linux 发行版默认安装,其内嵌的 chmod 实现不依赖系统 (/bin/chmod),可直接调用完成权限修改。

操作步骤:

  1. 若未安装 busybox,先启用对应源并安装(以 Ubuntu 为例):

    bash 复制代码
    sudo apt update && sudo apt install busybox

    优先推荐安装 busybox-static,避免依赖动态链接器。

  2. 执行修复命令:

    bash 复制代码
    sudo busybox chmod 0755 /bin/chmod

    适用条件:系统中已安装 BusyBox(Ubuntu 系统默认已预装,可直接执行第二步)。

2.3 可执行文件覆盖法(加载器不可用时)

原理:利用 cp 复制一个具有执行权限的系统文件(如 ls、chown),保留其执行权限位,再用原 chmod 文件内容覆盖该副本,最终通过副本恢复原 chmod 的权限;cp 会复制源文件的权限位,后续覆盖操作仅修改文件内容,不改变 inode 中的权限属性。

提供两种方案,按需选择:

方案1(cat 实现)

  1. 复制具有执行权限的文件作为载体:
bash 复制代码
cp /bin/ls /bin/chmod.tmp
  1. 用原 chmod 内容覆盖载体,保留载体的执行权限:
bash 复制代码
cat /bin/chmod > /bin/chmod.tmp
  1. 用载体恢复原 chmod 权限:
bash 复制代码
/bin/chmod.tmp 755 /bin/chmod
  1. 清理临时文件:
bash 复制代码
rm -f /bin/chmod.tmp

方案2(dd 实现)

  1. 备份原 chmod 文件:

    bash 复制代码
    mv /bin/chmod /bin/chmod.orig
  2. 复制具有执行权限的文件作为载体:

    bash 复制代码
    cp -a /bin/chown /bin/chmod
  3. 用原 chmod 内容覆盖载体,保留权限位:

    bash 复制代码
    dd if=/bin/chmod.orig of=/bin/chmod
  4. (可选)恢复完成后删除备份:

    bash 复制代码
    rm -f /bin/chmod.orig

方案3(cp 直接覆盖)

  1. 复制 ls 并保留其可执行权限:

    bash 复制代码
    sudo cp -p /usr/bin/ls /tmp/chmod
  2. 用 chmod 内容覆盖副本(保留可执行权限):

    bash 复制代码
    sudo cp /usr/bin/chmod /tmp/chmod
  3. 用副本修复原 chmod 权限:

    bash 复制代码
    sudo /tmp/chmod 755 /usr/bin/chmod
  4. 清理临时文件:

    bash 复制代码
    rm -f /tmp/chmod

补充:/tmp 目录会在系统重启后自动清空,若忘记清理也无需担心。

2.4 install 命令法(依赖 coreutils)

原理:install 是 GNU 基本工具,其 -m 选项可在复制文件时直接设置权限模式,创建新 inode 并赋予指定权限,无需依赖原文件权限,不依赖正常的 chmod 命令。

操作命令:

  1. 复制 chmod 并设置权限为 755 到临时目录:
bash 复制代码
sudo install -m 755 /bin/chmod /tmp/chmod

补充:install 命令默认权限即为 755,可省略 -m 755 参数,直接执行:

bash 复制代码
sudo install /bin/chmod /tmp/chmod
  1. 用临时文件恢复原 chmod 权限:
bash 复制代码
sudo /tmp/chmod 755 /bin/chmod
  1. (可选)清理临时文件:
bash 复制代码
rm -f /tmp/chmod

注意:需确保 install 命令本身(通常位于 (/usr/bin/install))权限正常。

2.5 脚本语言法(脚本环境可用时)

原理:Python、Perl 等脚本语言的相关函数直接封装内核 chmod() 系统调用,不依赖 (/bin/chmod) 可执行文件,仅需脚本解释器权限正常。

2.5.1 Python 方案

  1. 单行模式
bash 复制代码
sudo python3 -c 'import os; os.chmod("/bin/chmod", 0o755)'
  1. 脚本模式

    python 复制代码
    #!/usr/bin/env python3
    import os
    import stat
    
    os.chmod("/bin/chmod", stat.S_IRWXU | stat.S_IRGRP | stat.S_IXGRP | stat.S_IROTH | stat.S_IXOTH)

    补充:系统仅提供 Python2 时,使用如下命令:

    bash 复制代码
    sudo python -c 'import os; os.chmod("/bin/chmod", 0755)'

2.5.2 Perl 方案

bash 复制代码
sudo perl -e 'chmod 0755, "/bin/chmod"'

2.6 C 语言程序法(无其他工具时)

原理:通过 C 语言直接调用 chmod() 系统调用,编译后生成可执行文件,无需依赖系统工具,适用于无其他可用工具的场景。

  1. 创建源码文件(fix_chmod.c)

    c 复制代码
    #include <sys/stat.h>
    #include <stdio.h>
    
    int main(void)
    {
        if (chmod("/bin/chmod", 0755) != 0) {
            perror("chmod failed");
            return 1;
        }
        return 0;
    }
  2. 编译与执行

    bash 复制代码
    # 编译生成可执行文件
    gcc -o fix_chmod fix_chmod.c
    # 或使用 make 编译
    make CFLAGS="-Wall -O" fix_chmod
    
    # 执行修复
    sudo ./fix_chmod
    
    # 清理文件(可选)
    rm -f fix_chmod fix_chmod.c

    补充:系统未安装编译器时,可在同架构正常主机编译后,复制至故障系统执行。

2.7 Go 语言编译法

原理:通过 Go 语言调用os.Chmod 函数,该函数封装内核 chmod() 系统调用,编译后生成独立可执行文件,不依赖 chmod 命令。

  1. 创建源码文件(chmodan.go)

    go 复制代码
    package main
    
    import (
        "fmt"
        "os"
    )
    
    func main() {
        fileName := "/bin/chmod"
        err := os.Chmod(fileName, 0755)
        if err != nil {
            fmt.Println("Error os chmod work:", err)
            return
        }
        fmt.Println("File permissions have been successfully changed.")
    }
  2. 编译与执行

    bash 复制代码
    # 编译生成可执行文件
    go build chmodan.go
    
    # 执行修复
    sudo ./chmodan
    
    # 清理文件(可选)
    rm -f chmodan chmodan.go

2.8 ACL 临时授权法(文件系统支持时)

原理:通过文件访问控制列表(ACL)临时赋予 (/bin/chmod) 执行权限,恢复标准权限后再清除 ACL,避免残留权限配置,无需依赖正常的 chmod 命令。

操作命令:

  1. 临时添加 ACL 执行权限(仅 root 可执行):

    bash 复制代码
    setfacl -m u::rx /bin/chmod
  2. 使用 chmod 恢复标准权限(此时已可执行):

    bash 复制代码
    chmod 755 /bin/chmod
  3. 清除 ACL 配置,恢复默认权限模式:

    bash 复制代码
    setfacl -b /bin/chmod

适用条件:文件系统支持并启用了 ACL(如 ext4 的 acl 挂载选项),且 setfacl 命令自身权限正常。

2.9 dpkg-statoverride 法(Ubuntu/Debian 专属)

原理:dpkg-statoverride 是 Ubuntu/Debian 系统默认工具,用于强制覆盖文件的属主和权限,无需依赖 chmod 命令,适用于 Debian 系发行版。

操作指令:
bash sudo dpkg-statoverride --update --add root root 755 /bin/chmod

2.10 rsync 直接修改权限法

原理:rsync 在归档模式(-a)下,可仅修改文件权限而不改变文件内容,直接将 chmod 文件权限设为 755,无需依赖 chmod 命令。

操作指令:
bash sudo rsync -a --chmod=755 /bin/chmod /bin/chmod

2.11 tar 命令修改权限法

原理:tar 打包时可强制指定文件权限,解压时会应用该权限,root 可无视原文件权限读取并打包,无需依赖 chmod 命令,适用于无其他工具的场景。

分为两种方式,按需选择:

方式 1:现代 GNU tar 直接改权限

bash 复制代码
cd /bin
tar --mode 755 -cf chmod.tar chmod  # 打包时强制设权限为755
tar -xf chmod.tar                  # 解压,应用755权限
rm -f chmod.tar  # (可选)清理打包文件

方式 2:旧版手动修改 tar 包权限字段

bash 复制代码
cd /bin
tar -cf chmod.tar chmod            # 打包 chmod 文件
hexedit chmod.tar                  # 用十六进制编辑器,将包内 0000222 改为 0000755
tar -xf chmod.tar                  # 解压,权限生效
rm -f chmod.tar  # (可选)清理打包文件

2.12 Emacs 内置函数法(已安装 Emacs 时)

原理:Emacs 内置 set-file-modes 函数,直接调用 chmod() 系统调用,不依赖 (/bin/chmod) 命令,适用于已安装 Emacs 的系统。

操作步骤:

  1. 打开 Emacs 编辑器;
  2. 按快捷键 C-x C-f,输入 (/bin),打开 /bin 目录;
  3. 找到 chmod 文件,选中该文件;
  4. 按快捷键 M(运行 dired-do-chmod 命令);
  5. 在弹出的输入框中输入 755,确认后即可恢复权限。
    补充:Emacs 帮助文档明确说明,set-file-modes 是内置函数,直接调用系统调用,无需依赖外部 chmod 命令。

2.13 外部系统复制法(远程救援)

原理:从正常运行的同架构、同 glibc 版本的 Linux 系统,复制 chmod 二进制文件到故障主机,再用该文件恢复权限,适用于远程救援场景。

操作步骤:

  1. 在正常主机上,复制 chmod 到故障主机:

    bash 复制代码
    scp normal_host:/bin/chmod root@broken-host:/tmp/mychmod
  2. 在故障主机上,恢复权限:

    bash 复制代码
    install -m 755 /tmp/mychmod /bin/chmod
  3. (可选)清理临时文件:

    bash 复制代码
    rm -f /tmp/mychmod

注意:

  • 需确保源主机与目标主机架构一致(x86_64 / aarch64 等);
  • 需保证 glibc 版本兼容,避免因符号版本差异导致程序无法运行;
  • 切勿使用 cat /tmp/mychmod > /bin/chmod 后直接执行,重定向写入会保留原文件 000 的权限位。

2.14 重装 coreutils 软件包

原理:(/bin/chmod) 属于 coreutils 软件包的一部分,重装该包会自动将 chmod 文件及其权限恢复为系统默认值,是安全、彻底的官方修复方法。

操作指令:

bash 复制代码
sudo apt install --reinstall coreutils

适用条件:系统可正常启动、能使用 sudo 和 apt 命令的场景,修复后无需手动调整其他权限。

2.15 Live CD / 救援模式(所有方法失效时)

适用场景:当动态链接器、BusyBox、脚本解释器等组件权限均被破坏,系统无法正常操作时,使用此方法。

操作步骤:

  1. 使用 Linux 安装介质(U盘 / ISO)启动故障主机,进入 Live 模式;

  2. 挂载故障系统的根分区(假设根分区为 /dev/sda1):

    bash 复制代码
    mount /dev/sda1 /mnt/sysroot
  3. 直接修改 chmod 权限:

    bash 复制代码
    chmod 755 /mnt/sysroot/bin/chmod
  4. 卸载分区:

    bash 复制代码
    umount /mnt/sysroot

重启系统即可。

三、注意事项

  1. 所有方法均需 root 权限(sudo),否则会提示权限不足;
  2. 修复后建议核对 /bin 下其他文件权限(如 mount、su、ls 等),部分文件默认权限并非 755,可对照正常系统修正,避免因批量误操作导致其他命令无法使用;
  3. 学习 chmod 命令时,建议在虚拟机或容器中测试,避免在生产系统中误操作,尤其是 chmod -R 000 /bin 这类批量修改权限的命令;
  4. 使用动态链接器法时,需确认动态链接器自身权限正常,若动态链接器也被设为 000,需直接使用 Live CD 修复;
  5. 外部系统复制法中,需确保源主机与目标主机架构、glibc 版本兼容,避免出现程序无法运行的情况;
  6. 使用 tar、cp、dd 等命令覆盖文件时,建议先备份原文件,避免操作失误导致文件损坏;
  7. ACL 临时授权法仅适用于支持 ACL 的文件系统,若执行 setfacl 提示不支持,可换用其他方法;
  8. dpkg-statoverride 法仅适用于 Ubuntu/Debian 系发行版,CentOS、Alpine 等系统需换用其他方法。

恢复方法对比

恢复方法 依赖条件 复杂度 适用场景 优势
动态链接加载器法 glibc/musl、动态链接 ELF、加载器权限正常 首选方案,无额外工具依赖 原生可用,操作简单,无残留
BusyBox 法 系统已安装 BusyBox 运维应急,快速恢复 命令简洁,通用性强
可执行文件覆盖法 存在其他可执行系统文件 加载器不可用,无脚本环境 不依赖工具,稳定性高
ACL 临时授权法 文件系统支持并启用 ACL 文件系统支持 ACL 时 临时授权,恢复后无残留
install 命令法 coreutils 工具集正常 简单场景,快速重建文件 直接设置权限,步骤简洁
Python / Perl 法 对应脚本解释器正常 脚本环境可用,无其他便捷工具时 命令简洁,无需编译,易操作
C 语言程序法 系统编译器正常(gcc/make) 无其他工具可用,有编译环境 底层调用系统,兼容性强
Go 语言编译法 系统Go环境正常 熟悉 Go 语言,无其他便捷工具 生成独立可执行文件,无额外依赖
dpkg-statoverride 法 Ubuntu/Debian 系统、dpkg 工具正常 Ubuntu/Debian 系专属 强制覆盖权限,官方适配
rsync 直接修改法 rsync 命令权限正常 简单场景,快速修改权限 仅改权限不碰内容,安全高效
tar 命令修改法 tar 命令权限正常 无其他工具,tar 可用 兼容旧版系统,操作灵活
Emacs 内置函数法 系统已安装 Emacs 已安装 Emacs,快速操作 无需额外命令,内置函数直接调用
外部系统复制法 同架构正常主机、scp 可用 远程救援,本地工具失效 跨主机恢复,适合远程运维
重装 coreutils 法 系统可正常使用 apt,coreutils 可重装 安全彻底修复,系统可用 官方方法,无残留,可恢复所有核心命令
Live CD / 救援模式 Linux 安装介质、根分区可挂载 所有方法失效,系统异常 万能修复,适用于极端场景

reference