zoukankan      html  css  js  c++  java
  • 关于so文件cp覆盖导致调用者core的研究

    先说cp好mv/rm的区别:

    cp from to,则被覆盖文件 to的inode依旧不变(属性也不变),内容变为from的;

    mv from to,则to的inode变为from的,相应的,to的属性也成了from的;rm类似;

    问题,假如程序 main.out依赖的so文件libtest.so被cp掉,会发生什么?

    strace cp test2 test  2>&1 | grep open.*test
    open("test2", O_RDONLY|O_LARGEFILE)     = 3
    open("test", O_WRONLY|O_TRUNC|O_LARGEFILE) = 4

      cp的实现逻辑不是“rm + open(O_CREAT)”,而上面的实现方式才是最可靠的(保证了时序安全和目标文件的属性)。这解释了为什么cp的目标文件会继承被覆盖文件的属性而非源文件。

    Linux由于Demand Paging机制的关系,必须确保正在运行中的程序镜像(注意,并非文件本身)不被意外修改,因此内核在启动程序后会绑定 内存页 到这个so的inode,而一旦此inode文件被open函数O_TRUNC掉,则kernel会把so文件对应在虚存的页清空,这样当运行到so里面的代码时,因为物理内存中不再有实际的数据(仅存在于虚存空间内),会产生一次缺页中断。Kernel从so文件中copy一份到内存中去,a)但是这时的全局符号表并没有经过解析,当调用到时就产生segment fault , b)如果需要的文件偏移大于新的so的地址范围,就会产生bus error。

    备注:如果用相同的so去cp覆盖
    A) 如果so 里面依赖了外部符号(如标准库),coredump
    B) 如果so里面没有依赖外部符号,运气不错,不会coredump

    不必说,先rm再cp的话,新文件的inode其实已经改变了,原inode并没有被真正删除,直到内核释放对它的引用(引用旧SO的进程退出,而新进程当然呈现的就是新so的效果了,新进程和core无关啦)。同理,mv只是改变了文件名,其inode不变,新文件使用了新的inode。

    参考: 

    [1]http://www.piao2010.com/%E4%B8%BA%E4%BD%95cp%E8%A6%86%E7%9B%96%E8%BF%9B%E7%A8%8B%E7%9A%84%E5%8A%A8%E6%80%81%E5%BA%93so%E4%BC%9A%E5%AF%BC%E8%87%B4coredump

    [2]http://blog.csdn.net/wei_yongtao/article/details/40145891

  • 相关阅读:
    复杂对象类型的WebService高级部分
    linux 免输入密码脚本
    查看端口是否被占用
    shell将脚本输出结果记录到日志文件
    多线程注意点
    apache Tomcat配置SSL(https)步骤
    常用的web安全处理
    SQL 中的 UNION 和UNION ALL 的区别
    数据库和数据仓库区别
    Oracle数据库创建表是有两个约束带有默认索引
  • 原文地址:https://www.cnblogs.com/zhaoyl/p/4964811.html
Copyright © 2011-2022 走看看