一个指定LD_PRELOAD的进程创建的子进程是否受LD_PRELOAD的影响?

1.

fork()后在子进程中执行函数。

main.c

#include <unistd.h>
#include <stdio.h>

extern char** environ;
void foo();
int main()
{
        for(char **current = environ; *current; current++) {
            puts(*current);
        }
        if(0 == fork()){
                foo();
        }else{
                sleep(1);
        }
        return 0;
}

foo.c

#include <stdio.h>
void foo()
{
        printf("real foo\n");
}

wfoo.c

#include <stdio.h>

void foo()
{
        printf("wrap foo\n");
}

将以上代码编译成执行文件和动态库

  • gcc -fPIC -shared foo.c -o libfoo.so
  • gcc -fPIC -shared wfoo.c -o libwfoo.so
  • gcc main.c -L./ -lfoo

执行LD_PRELOAD=./libwfoo.so ./a.out,其输出如下

[root@localhost ~]# LD_LIBRARY_PATH=./ LD_PRELOAD=./libwfoo.so ./a.out
LD_PRELOAD=./libwfoo.so
....
其他环境变量
...
wrap foo

也就是说fork()后的子进程其函数地址是和父进程一样的。

先执行了export LD_LIBRARY_PATH=./

仔细想了一想,fork()创建子进程,子进程仍使用父进程的代码段,这和LD_PRELOAD并没有关系。

2.

创建子进程后执行exec簇函数
exec.c

#include <unistd.h>

int main()
{
        if(0 == fork()){
                execl("./a.out", "./a.out", NULL);
        }
        return 0;
}

gcc exec.c -o exec

[root@localhost ~]# LD_PRELOAD=./libwfoo.so ./exec
LD_PRELOAD=./libwfoo.so
....
其他环境变量
...
wrap foo

如果将excel()替换为excele(),则情况发生变化

[root@localhost ~]# ./exec
./a.out: error while loading shared libraries: libfoo.so: cannot open shared object file: No such file or directory

这意味着LD_LIBRARY_PATH环境变量失效了。

仔细阅读man 3 exec后,恍然大悟。exec函数簇可分为两类,一类将当前进程的char** environ指向的环境变量传递给新程序镜像,如execl(),另一类则只使用函数参数指定的环境变量,如execle()

综上,当使用execle()这类函数时,如果没有手动将当前进程的环境变量通过参数传递下去,那么就会使得LD_PRELOAD失效,无法实现函数拦截的功能了。

3.

使用system()创建的子进程同样继承环境变量
exec.c

#include <unistd.h>

int main()
{
        if(0 == fork()){
                system("./a.out");
        }
        return 0;
}

gcc exec.c -o exec

[root@localhost ~]# LD_LIBRARY_PATH=./ LD_PRELOAD=./libwfoo.so ./exec
LD_PRELOAD=./libwfoo.so
....
其他环境变量
...
wrap foo

4.

结合以上情况,只有在特意指定子进程环境变量的情况(使用execle()等函数),原先指定的环境变量才会失效,否则环境变量都会传递到子进程。

子进程的LD_PRELOAD的更多相关文章

  1. UNIX下的LD_PRELOAD环境变量

    UNIX下的LD_PRELOAD环境变量 也许这个话题并不新鲜,因为LD_PRELOAD所产生的问题由来已久.不过,在这里,我还是想讨论一下这个环境变量.因为这个环境变量所带来的安全问题非常严重,值得 ...

  2. [forward]警惕UNIX下的LD_PRELOAD环境变量

    From: https://blog.csdn.net/haoel/article/details/1602108 警惕UNIX下的LD_PRELOAD环境变量 前言 也许这个话题并不新鲜,因为LD_ ...

  3. LD_PRELOAD & putenv() 绕过 disable_functions & open_basedir

    这次TCTF中一道题,给出了一个PHP一句话木马,设置了open_basedir,disable_functions包含所有执行系统命令的函数,然后目标是运行根目录下的/readflag,目标很明确, ...

  4. Node.js:进程、子进程与cluster多核处理模块

    1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...

  5. MapReduce剖析笔记之七:Child子进程处理Map和Reduce任务的主要流程

    在上一节我们分析了TaskTracker如何对JobTracker分配过来的任务进行初始化,并创建各类JVM启动所需的信息,最终创建JVM的整个过程,本节我们继续来看,JVM启动后,执行的是Child ...

  6. PHP CLI编程基础知识积累(进程、子进程、线程)

    .note-content { font-family: "Helvetica Neue", Arial, "Hiragino Sans GB", STHeit ...

  7. 记一次WinForm程序中主进程打开子进程并传递参数的操作过程(进程间传递参数)

    目标:想在WinForm程序之间传递参数.以便子进程作出相应的处理. 一种错误的方法 父进程的主程序: ProcessStartInfo psi = new ProcessStartInfo(); p ...

  8. Android5.1.1源码 - zygote fork出的子进程如何权限降级

    前言 所有Android应用进程都是zygote fork出来的,新fork出来的应用进程还保持着root权限,这显然是不被允许的,所以这个fork出来的子进程的权限需要被降级,本文说的就是Andro ...

  9. fork()创建子进程

    fork()系统调用是Unix下以自身进程创建子进程的系统调用,一次调用,两次返回,如果返回是0,则是子进程,如果返回值>0,则是父进程(返回值是子进程的pid) 在fork()的调用处,整个父 ...

随机推荐

  1. 为什么Map桶中个数超过8才转为红黑树

    这是笔者一个好友面试阿里时,被问及的一个问题,应该不少人看到这个问题都会一面懵逼.因为,大部分的文章都是分析链表是怎么转换成红黑树的,但是并没有说明为什么当链表长度为8的时候才做转换动作.笔者第一反应 ...

  2. 剑指offer:链表中环的入口结点

    题目描述: 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路分析: 这道题首先需要判断链表是否存在环,很快就能想到用快慢指针来判断. 由于快慢指针的相遇位置并不一定为链 ...

  3. Spring cloud微服务安全实战-7-13章节总结

    日志信息可以放到kafka,像指标监控就可以从kafka里面拿出日志来,分析日志里面的东西,把日志里面的一些信息变成数字,比如某个关键字出现了多少次,这样的信息同样去做监控,做报警. 调用链监控也是和 ...

  4. vagrant报错处理

    vagrant up报错 Warning: Authentication failure. Retrying...解决方案 http://www.cnblogs.com/zqifa/p/vagrant ...

  5. vue地图可视化 ArcGIS篇

    ArcGIS for javascript开发心得 本次实例中采用ArcGIS for javascript3.24版本,由于版本3与4在API等存在较大区别,就不一一列举,详细区别看官方解释arcg ...

  6. [LeetCode] 80. Remove Duplicates from Sorted Array II 有序数组中去除重复项 II

    Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twic ...

  7. [LeetCode] 258. Add Digits 加数字

    Given a non-negative integer num, repeatedly add all its digits until the result has only one digit. ...

  8. python jieba

    https://www.cnblogs.com/jiayongji/p/7119065.html 安装 pip install jieba 简单用法 结巴分词分为三种模式:精确模式(默认).全模式和搜 ...

  9. elasticsearch 管理常用命令集合

    elasticsearch rest api遵循的格式为: curl -X<REST Verb> <Node>:<Port>/<Index>/<T ...

  10. 阿里云使用Docker部署工单系统(redmine)

    环境:阿里云服务器 Redmine安装部署 Redmine是用Ruby开发的基于web的项目管理软件,是用ROR框架开发的一套跨平台项目管理系统,据说是源于Basecamp的ror版而来,支持多种数据 ...