无法使用 `capsh` 的 `==` 参数重新执行它?

无法使用 `capsh` 的 `==` 参数重新执行它?

我正在尝试capsh( libcap2-bin1:2.32-1) ,但发现我无法使用参数==来重新执行capsh

特别是,当我使用capsh's==参数时,它抱怨它不能使用execve(2)shell /bin/bash

有人尝试过类似的问题吗?

ls -la /bin/bash
-rwxr-xr-x 1 root root 1183448 Jun 18  2020 /bin/bash

capsh --help
...
==             re-exec(capsh) with args as for --
...

capsh == --print
execve /bin/bash failed!

capsh --print
Current: =
Bounding set =cap_chown,cap_dac_override,cap_dac_read_search,cap_fowner,cap_fsetid,cap_kill,cap_setgid,cap_setuid,cap_setpcap,cap_linux_immutable,cap_net_bind_service,cap_net_broadcast,cap_net_admin,cap_net_raw,cap_ipc_lock,cap_ipc_owner,cap_sys_module,cap_sys_rawio,cap_sys_chroot,cap_sys_ptrace,cap_sys_pacct,cap_sys_admin,cap_sys_boot,cap_sys_nice,cap_sys_resource,cap_sys_time,cap_sys_tty_config,cap_mknod,cap_lease,cap_audit_write,cap_audit_control,cap_setfcap,cap_mac_override,cap_mac_admin,cap_syslog,cap_wake_alarm,cap_block_suspend,cap_audit_read
Ambient set =
Securebits: 00/0x0/1'b0
 secure-noroot: no (unlocked)
 secure-no-suid-fixup: no (unlocked)
 secure-keep-caps: no (unlocked)
 secure-no-ambient-raise: no (unlocked)
uid=1000(parallels) euid=1000(parallels)
gid=1000(parallels)
groups=4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),120(lpadmin),131(lxd),132(sambashare),1000(parallels)
Guessed mode: UNCERTAIN (0)

答案1

capsh问题是它试图以(或您启动它时使用的任何命令名称和路径)重新执行自身。

这是来自strace capsh == --print

execve("capsh", ["capsh", "--print"], [/* 20 vars */]) = -1 ENOENT (No such file or directory)
write(2, "execve /bin/bash failed!\n", 25execve /bin/bash failed!
) = 25

execve /bin/bash所以失败并不是真正的“ ”,而是execve capsh。该execve()函数不在 中进行查找$PATH

使用capsh它的完整路径将使它工作。

$ command -v capsh
/sbin/capsh
$ /sbin/capsh == --print
Current: =
[... etc. ...]

另请参阅execve(2)系统手册 ( man 2 execve)。

答案2

这可能是我们去年修复的 libcap:capsh 中的一个错误:

https://bugzilla.kernel.org/show_bug.cgi?id=209873

如果 2.45 之后的 libcap 版本中这仍然是一个问题,请告诉我。

答案3

如果我找到的源代码是正确的,它看起来对==和都使用相同的几行--

    } else if ((!strcmp("--", argv[i])) || (!strcmp("==", argv[i]))) {
        argv[i] = strdup(argv[i][0] == '-' ? "/bin/bash" : argv[0]);
        argv[argc] = NULL;
        execve(argv[i], argv+i, envp);
        fprintf(stderr, "execve /bin/bash failed!\n");
        exit(1);
    }

就像 Kusalananda 所说,它不会找到,capsh因为execve()它不查找路径,并且错误消息是针对这种/bin/bash情况进行硬编码的。

相关内容