调用capset失败:无法仅保留CAP_SETUID权限排查
问题原因分析
你的capset调用失败返回EPERM,核心原因是非root有效UID(euid≠0)的进程无法缩小自身的permitted权限集。
虽然你的进程当前permitted和effective集合包含CAP_SETUID及其他权限,但当你尝试把permitted集合从多权限缩减为仅CAP_SETUID时,若进程的有效UID不是0,Linux内核会阻止这个操作——因为permitted集是进程能拥有的权限上限,非root进程不允许永久移除自身permitted集中的权限。
解决办法
仅调整effective权限集:如果你只需要让进程实际使用
CAP_SETUID权限,无需修改permitted集合。修改capset调用,保持permitted集不变,仅将effective集设置为1<<CAP_SETUID:capset( {version=_LINUX_CAPABILITY_VERSION_3, pid=0}, {effective=1<<CAP_SETUID, permitted=1<<CAP_SETGID|1<<CAP_SETUID|1<<CAP_SETPCAP|1<<CAP_NET_BIND_SERVICE|1<<CAP_NET_ADMIN|1<<CAP_NET_RAW|1<<CAP_SYS_ADMIN, inheritable=0} )这样操作符合非root进程的权限规则,不会触发
EPERM。切换到root有效UID再修改permitted集:若你确实需要缩小permitted集,必须先将进程的有效UID切换为0(通过
setuid(0),前提是进程的saved UID是0或拥有CAP_SETUID权限),完成capset修改后再切换回原UID。
内容的提问来源于stack exchange,提问作者Siscia
相关产品推荐
相关产品推荐

