我想以非特权用户身份运行一个服务,但它需要绑定到系统端口号(即小于1024),所以我给了它setcap 'cap_net_bind_service=+ep' <path for service>
,一切都很好。
问题是,在启动时,该服务会读取环境变量,并且由于某种原因,当它具有cap_net_bind_service
.因此,有两份可执行文件的副本,一份带有cap_net_bind_service
,一份没有,只有没有的一份可以读取环境变量。
就好像有一组默认的功能允许读取环境变量,但是当我提供它时,exe 就失去了该功能cap_net_bind_service
。是这样吗,还是有其他事情发生?我可能需要为该服务提供哪些附加功能,以便它可以读取环境变量?里面什么都没有能力.h跳出来是“允许环境变量读取”?
答案1
我已经追根究底了。简而言之,二进制文件正在使用secure_getenv
访问环境变量。当二进制文件在“安全执行”模式 ( )下运行时,这会返回null
,而不是访问变量。AT_SECURE=1
设置任何功能后,都会使其在此模式下运行。
确认二进制文件正在secure_getenv
使用readelf
:
readelf -a <path for service> | grep getenv
00000040ac28 004b00000007 R_X86_64_JUMP_SLO 0000000000000000 secure_getenv@GLIBC_2.17 + 0
00000040ad90 007a00000007 R_X86_64_JUMP_SLO 0000000000000000 getenv@GLIBC_2.2.5 + 0
75: 0000000000000000 0 FUNC GLOBAL DEFAULT UND secure_getenv@GLIBC_2.17 (6)
122: 0000000000000000 0 FUNC GLOBAL DEFAULT UND getenv@GLIBC_2.2.5 (2)
确认它正在使用环境变量以安全执行模式运行(多么讽刺!)LD_DEBUG=all
和/或LD_SHOW_AUXV
(请参阅man ld.so
)。
如果不是,则LD_SHOW_AUXV
生成设置为 0 的输出。在安全执行模式下运行时AT_SECURE
没有输出。LD_SHOW_AUXV
LD_DEBUG
通常,当它在/不在安全执行模式下运行时,too有/没有输出。但是,如果/etc/suid-debug
存在(空文件,通过触摸创建),则LD_DEBUG
在安全执行模式下运行时将产生输出。
看man getauxval
有关AT_SECURE
安全执行模式的更多信息。