前提:
循环在 /dev/shm 下创建大文件,并且处理完成后删除
现在调试需要,把文件通过 sftp 方式下载到 win 主机下,由于网络原因传输速度慢,导致文件还没传输完,linux 端已经执行了删除文件,但是这边 sftp 传输并没有报错,也没有停止,直到传输完成,文件传输回来看了一下也是正常的,这是什么原理,有没有大佬指点下
发散了一下思维: 由于 /dev/shm 是内存盘,是否有可能我创建一个大文件,记录下内存地址,然后删除文件,再篡改该内存块的数据达到篡改文件的目的(我理解的是这文件已经删除所以这块地址已经不受保护)
文件描述符还没被释放呢吧…
Linux 要等所有引用都结束之后才会真正删除文件
/dev/shm 是 tmpfs 文件系统,文件不会写到硬盘上,重启之后文件就没了。
我意思是不等重启,在形式上删除之后,进行修改,能否达到目的~
我用 lsof 查看确实还是占用状态,只是后面标记了 delete,也就是说文件并没有真正删除,只是用 ls 看不到而已,那这块空间也就没有释放对吧
但是我实测的是:我设定 /dev/shm 空间为 256m,我写入一个 255m 的文件,然后打开传输,传输过程中,删除文件,这时候再往 /dev/shm 里写入第二个 255m 的文件前,用 du . -h 查看文件夹占用,已经是 0m (/dev/shm 已经空了),再写入文件时依然可以写入啊,那是不是就覆盖了前一块占用的内存空间呢?
应该是文件描述符未释放,我没想明白的地方是这块文件的数据 现在存在哪里,以及能不能修改
说明只是被 mark 为 已删除 而已,还没强制回收。其实还在老地方,等着被新数据覆盖。
同意 文件描述符未释放 lsof -n|grep 'delete' 应该可以看到
linux 下 不就有个回复删除文件的小技巧么 只要 某个删除文件有进程占用 找到 进程 pid 和 文件 fd
cat /proc/pid/fd/fd_num > /home/xxx
就还原了
补充一下原理:shmem_unlink 也就是你执行的删除动作,会参考 inode->i_nlink 硬链接计数,然后执行 drop_nlink 才会被 filesystem 彻底释放的(虽然不是块数据,但是数据还在 cache,等着停电丢失、覆盖或被强制逐出)
“我理解的是这文件已经删除所以这块地址已经不受保护”
错
文件删除只是删除了路径,实际文件,以及其所占用的空间并没有被释放。只有当所有打开的描述被关闭时才会真正释放相关资源
这一点 Linux 和 Windows 是不同的。Windows 默认会锁文件,所以删不掉打开的文件。
篡改 /dev/shm 的文件的问题是如何在用户空间获取这个文件的地址呢?没法绕过虚拟地址到物理地址映射啊
对于设定限制大小的 /dev/shm 文件夹(比如 256M ),我的想法是只需要操作删除这个文件夹下所有文件,然后按照再创建一个和文件夹相当的文件(类似 255M ),就能达到覆盖原始文件的操作了,只是不知道这样的操作有没有可能触发什么漏洞
delete 只是 unlink 么,可是通过 du -h . 看到的文件夹大小已经是释放出来的,也就是剩余的空间我可以使用的,尽管实际在进程中文件描述符还在使用,但所指向数据块 已经是可以被覆盖的区域了
那你要研究一下何谓“释放”了,只要硬链接计数没达到释放的阈值,就不会被覆盖。这点可以参考下 VFS 的设计
内存不够用的话是会用 swap 的