一个指定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. 安装Nvidia显卡驱动、CUDA和cuDNN的方法(jsxyhelu整编)

    Nvidia显卡驱动.CUDA和cuDNN一般都是同时安装的,这里整理的是我成功运行的最简单的方法. 一.Nvidia显卡驱动 1.1 在可以进入图形界面的情况下 直接在"软件和更新&quo ...

  2. 【翻译】Flink Table Api & SQL —Streaming 概念 ——在持续查询中 Join

    本文翻译自官网 :  Joins in Continuous Queries   https://ci.apache.org/projects/flink/flink-docs-release-1.9 ...

  3. [LeetCode] 499. The Maze III 迷宫 III

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  4. [LeetCode] 534. Design TinyURL 设计短网址

    Note: For the coding companion problem, please see: Encode and Decode TinyURL. How would you design ...

  5. 570. Managers with at Least 5 Direct Reports 至少有5个直接汇报员工的经理

    The Employee table holds all employees including their managers. Every employee has an Id, and there ...

  6. IFC文件介绍

    IFC是一个数据交换标准, 用于不同系统交换和共享数据. IFC是采用EXPRESS语言定义的实体关系模型,由几百个实体对象组成.实体对象包括建筑要素如IfcWall,几何元素如IfcExtruded ...

  7. Layer文件上传同时传递表单数据

    (1)index.html <!DOCTYPE html> <html> <head> <title>TODO supply a title</t ...

  8. python 实现微信发送消息

    背景:利用Python来登入你个人的手机微信,之后向朋友发送消息,发送的消息可以来源于网页.下面的例子就是取得当前日元的汇率,之后发送自己的某一个朋友的手机上 环境:Python3,JetBrains ...

  9. html5+springboot+websocket的简单实现

    环境 window7,IntelliJ IDEA 2019.2 x64 背景:利用IntelliJ来搭建springboot框架,之后来实现websocket的功能.websocket只是实现了画面上 ...

  10. Ubuntu 18.04 安装远程桌面

    原文链接:https://baijiahao.baidu.com/s?id=1619271691270163095&wfr=spider&for=pc 安装 tightvncserve ...