一个指定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. 龙格-库塔法解常微分方程(c++)

    用龙格库塔法计算 #include <iostream> #include<iomanip> #include <cmath> using namespace st ...

  2. hdoj - 1506 直方图中最大的矩形

    Problem Description A histogram is a polygon composed of a sequence of rectangles aligned at a commo ...

  3. 2015-2016-2《Java程序设计》团队博客1

    项目内容 经过一些讨论之后决定了最终的项目:简易画图板项目设计与开发 目标 制作一个能够画各种图形的画板,并能有多种颜色可以选择:输入文本时也可以选择字体:能够保存,新建,和导入图片 实现计划 十一周 ...

  4. Git提交(PUSH)时记住密码 - 不用每次都输入密码

    开发使用的团队搭建好的GitLab服务器来作为项目共享开发,由于我不是最高权限,没办法把我git生成的SSH-Key放到服务器里面去,所有只好在每次提交的时候配置git config来记录密码不过期来 ...

  5. (二)OpenCV-Python学习—对比度增强

    ·对于部分图像,会出现整体较暗或较亮的情况,这是由于图片的灰度值范围较小,即对比度低.实际应用中,通过绘制图片的灰度直方图,可以很明显的判断图片的灰度值分布,区分其对比度高低.对于对比度较低的图片,可 ...

  6. pytorch保证每次运行使用的随机数都相同的方法

    其实在代码的开头添加下面几句话即可: # 保证训练时获取的随机数都是一样的 init_seed = torch.manual_seed(init_seed) torch.cuda.manual_see ...

  7. 如何用java代码写一个堆栈

    public class Stack { int[] data; int maxSize; int top; public Stack(int maxSize) { this.maxSize = ma ...

  8. 网页视频直播、微信视频直播技术解决方案:EasyNVR与EasyDSS流媒体服务器组合之区分不同场景下的直播接入需求

    背景分析 熟悉EasyNVR产品的朋友们都知道,EasyNVR不仅可以独成体系,而且还可以跟其他系列产品相配合,形成各种不同类型的解决方案,满足各种不同应用场景的实际需求.针对很多设备现场没有固定公网 ...

  9. MySQL之Xtrabackup使用

    Xtrabackup对使用innodb存储引擎的mysql数据库进行备份时,不会影响数据库的读写操作(网上是这么说的,我还没验证过) 1.安装yum源 yum install https://repo ...

  10. mysql之各版本rpm包安装

    发现每次想用mysql的rpm包直接安装的时候,都会出现找不到对应的rpm包的情况,故记录一下查找过程 进入官网->downloads->community->mysql commu ...