setuid()之后失去能力

试图设置cap_setgid,cap_setuid,cap_setpcap.

#include 

执行是在root用户下进行的.
跟踪程序显示了这一点

capget({_LINUX_CAPABILITY_VERSION_3,0},NULL) = 0
capget({_LINUX_CAPABILITY_VERSION_3,{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_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,0}) = 0
capset({_LINUX_CAPABILITY_VERSION_3,CAP_SETGID|CAP_SETUID|CAP_SETPCAP}) = 0
setgid(65534)                           = 0
setuid(65534)                           = 0
capget({_LINUX_CAPABILITY_VERSION_3,{0,CAP_SETGID|CAP_SETUID|CAP_SETPCAP}) = 0
setgid(0)                               = -1 EPERM (Operation not permitted)
setuid(0)                               = -1 EPERM (Operation not permitted)
exit_group(0)                           = ?
+++ exited with 0 +++

权限已设置但不起作用.有什么建议如何解决这个问题?

更新:prctl添加到代码中

21a22
> prctl(PR_SET_KEEPCAPS,1,0);
24a26
> cap_set_flag(caps,3,CAP_SET);

所以现在是

prctl(PR_SET_KEEPCAPS,0);
setgid(65534);
setuid(65534);
cap_set_flag(caps,CAP_SET);

在setuid之后继承了上限,并且手动设置的上限仍然存在,但它没有解决问题

setgid(65534)                           = 0
setuid(65534)                           = 0
capget({_LINUX_CAPABILITY_VERSION_3,CAP_SETGID|CAP_SETUID|CAP_SETPCAP}) = 0
setgid(0)                               = -1 EPERM (Operation not permitted)
setuid(0)                               = -1 EPERM (Operation not permitted)
exit_group(0)                           = ?
+++ exited with 0 +++

UPDATE2:
无法理解.我已经在1st setuid之后添加了2次,以查看大写字母.

printf("cape set %d\n",cap_set_flag(caps,CAP_SET));
printf("%s\n",cap_to_text(cap_get_proc(),NULL));

它回来了

catp set 0
=p cap_setgid,cap_setpcap+i

未设置有效标志,但cap_set_flag返回0

最佳答案
默认情况下,功能集在UID转换中丢失;使用

prctl(PR_SET_KEEPCAPS,0);

保留允许的功能(cap_set_flag(大写,CAP_PERMITTED,…)).请注意,有效功能集将被重置,但可以重新建立.

以下工作对我来说很好.

#include 
$sudo strace ./a.out
...
capget({_LINUX_CAPABILITY_VERSION_3,0}) = 0
prctl(PR_SET_KEEPCAPS,1)               = 0
setgid(65534)                           = 0
setuid(65534)                           = 0
capget({_LINUX_CAPABILITY_VERSION_3,{CAP_SETGID|CAP_SETUID,0}) = 0
setgid(0)                               = 0
setuid(0)                               = 0
...

相关文章

查找全部容器的日志文件 $ sudo find /var/lib/docker/conta...
Linux日志文件中列属性的详细解析
在Linux系统中没有duf命令,如何有效地管理磁盘空间?
深入探讨EncryptPad在Linux操作系统中的功能和优势
原理和应用场景:Linux中ttyload工具的工作原理和实际用途
深度解析SELinux的三种策略类型