微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

使用Linux功能是否会禁用LD_PRELOAD

在我的自定义环境中,预加载一个拦截器库,它运行bind(),connect()等调用的特殊实现.

我看到的问题是,只要应用程序使用命令setcap显式启用功能,执行应用程序就无法预加载拦截器库并调用认的libc connect().

这是预期的行为吗?如果是,那么禁用LD_PRELOAD的原因是什么?

是否有任何调整或方法可用于成功预加载启用功能的库.

解决方法

就像Oliver Matthews所回答的那样,出于安全原因,LD_PRELOAD对于setuid二进制文件和具有文件功能的二进制文件都是禁用的.

要在仍启用文件功能的同时预加载库,您有两个选择:

>设置预加载的库setuid root

(Linux动态链接器ld.so甚至为setuid /文件功能启用的二进制文件预加载库,如果这些库由root拥有并标记为set-uid.)
>使用setuid根包装器

包装器获得完全root权限(真实和有效用户和组ID都为零),并将原始真实用户和组ID存储到例如环境变量).

预加载的库具有构造函数,例如

static void my_library_init(void) __attribute__((constructor));
static void my_library_init(void)
{
    /* ... */
}

它在main()之前自动运行(但可能在其他预加载库中的其他构造函数之后,或者在预加载库所依赖的库中).

此构造函数获取所需的功能,通过环境变量(getenv(),cap_from_text())或二进制可执行文件本身(cap_from_file(“/ proc / self / exe”))指定.

构造函数必须临时使用prctl(PR_SET_KEEPCAPS,1)来保持身份更改的功能,并保留CAP_SETUID和CAP_SETGID功能,以便能够将身份从root更改为环境变量中指定的用户和组,然后再将其自身限制为最终能力集.

两种选择都有明显的安全性考虑我建议在预加载的库构造函数中进行完整性检查(并清除LD_PRELOAD).如果有任何可疑之处,请使用_exit()立即中止该过程.

一般来说,我推荐第一个简单选项(实现和安全问题),但如果有某些原因无法使用,我也可以为第二种情况提供概念验证代码. (我已经验证了两个选项在Ubuntu 12.04.2 LTS上运行,使用ext4文件系统运行3.8.0-27通用x86-64内核.)

希望这可以帮助.

原文地址:https://www.jb51.cc/linux/393327.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐