/dev/shm 下文件删除后依然可以访问

2019-08-27 16:33:25 +08:00
 cshlxm

前提: 循环在 /dev/shm 下创建大文件,并且处理完成后删除

现在调试需要,把文件通过 sftp 方式下载到 win 主机下,由于网络原因传输速度慢,导致文件还没传输完,linux 端已经执行了删除文件,但是这边 sftp 传输并没有报错,也没有停止,直到传输完成,文件传输回来看了一下也是正常的,这是什么原理,有没有大佬指点下

发散了一下思维: 由于 /dev/shm 是内存盘,是否有可能我创建一个大文件,记录下内存地址,然后删除文件,再篡改该内存块的数据达到篡改文件的目的(我理解的是这文件已经删除所以这块地址已经不受保护)

5631 次点击
所在节点    Linux
15 条回复
DoctorCat
2019-08-27 16:34:24 +08:00
文件描述符还没被释放呢吧…
kxct
2019-08-27 17:10:33 +08:00
Linux 要等所有引用都结束之后才会真正删除文件
shelterz
2019-08-27 17:18:58 +08:00
/dev/shm 是 tmpfs 文件系统,文件不会写到硬盘上,重启之后文件就没了。
cshlxm
2019-08-27 17:32:40 +08:00
@shelterz 我意思是不等重启,在形式上删除之后,进行修改,能否达到目的~
cshlxm
2019-08-27 17:40:57 +08:00
@kxct 我用 lsof 查看确实还是占用状态,只是后面标记了 delete,也就是说文件并没有真正删除,只是用 ls 看不到而已,那这块空间也就没有释放对吧
但是我实测的是:我设定 /dev/shm 空间为 256m,我写入一个 255m 的文件,然后打开传输,传输过程中,删除文件,这时候再往 /dev/shm 里写入第二个 255m 的文件前,用 du . -h 查看文件夹占用,已经是 0m (/dev/shm 已经空了),再写入文件时依然可以写入啊,那是不是就覆盖了前一块占用的内存空间呢?
cshlxm
2019-08-27 17:42:17 +08:00
@DoctorCat 应该是文件描述符未释放,我没想明白的地方是这块文件的数据 现在存在哪里,以及能不能修改
DoctorCat
2019-08-27 18:22:22 +08:00
说明只是被 mark 为 已删除 而已,还没强制回收。其实还在老地方,等着被新数据覆盖。
ijustdo
2019-08-27 18:38:05 +08:00
同意 文件描述符未释放 lsof -n|grep 'delete' 应该可以看到
linux 下 不就有个回复删除文件的小技巧么 只要 某个删除文件有进程占用 找到 进程 pid 和 文件 fd
cat /proc/pid/fd/fd_num > /home/xxx
就还原了
DoctorCat
2019-08-27 19:07:43 +08:00
@cshlxm 补充一下原理:shmem_unlink 也就是你执行的删除动作,会参考 inode->i_nlink 硬链接计数,然后执行 drop_nlink 才会被 filesystem 彻底释放的(虽然不是块数据,但是数据还在 cache,等着停电丢失、覆盖或被强制逐出)
ryd994
2019-08-27 23:22:08 +08:00
“我理解的是这文件已经删除所以这块地址已经不受保护”

文件删除只是删除了路径,实际文件,以及其所占用的空间并没有被释放。只有当所有打开的描述被关闭时才会真正释放相关资源

这一点 Linux 和 Windows 是不同的。Windows 默认会锁文件,所以删不掉打开的文件。
zivyou
2019-08-28 11:17:20 +08:00
篡改 /dev/shm 的文件的问题是如何在用户空间获取这个文件的地址呢?没法绕过虚拟地址到物理地址映射啊
cshlxm
2019-08-28 12:32:21 +08:00
@zivyou 对于设定限制大小的 /dev/shm 文件夹(比如 256M ),我的想法是只需要操作删除这个文件夹下所有文件,然后按照再创建一个和文件夹相当的文件(类似 255M ),就能达到覆盖原始文件的操作了,只是不知道这样的操作有没有可能触发什么漏洞
cshlxm
2019-08-28 12:38:57 +08:00
@DoctorCat delete 只是 unlink 么,可是通过 du -h . 看到的文件夹大小已经是释放出来的,也就是剩余的空间我可以使用的,尽管实际在进程中文件描述符还在使用,但所指向数据块 已经是可以被覆盖的区域了
DoctorCat
2019-08-28 12:59:11 +08:00
@cshlxm 那你要研究一下何谓“释放”了,只要硬链接计数没达到释放的阈值,就不会被覆盖。这点可以参考下 VFS 的设计
exip
2019-08-30 06:33:03 +08:00
内存不够用的话是会用 swap 的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/595577

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX