当前位置:嗨网首页>书籍在线阅读

08-执行文件操作和文件IO的缺陷

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

38.7 执行文件操作和文件I/O的缺陷

如果一个特权进程需要创建一个文件,那么必须要小心处理那个文件的所有权和权限以确保文件不存在被恶意操作攻击的风险点,不管这个风险点有多小。因此需遵循下列指南。

  • 需要将进程的umask(参见15.4.6节)设置为一个能确保进程永远无法创建公共可写的文件的值,否则恶意用户就能修改这些文件了。
  • 由于文件的所有权是根据创建进程的有效用户ID来确定的,因此可能需要使用seteuid()或setreuid()来临时地修改进程的身份信息以确保新创建的文件不会属于错误的用户。由于文件的组所有权可能会根据进程的有效组ID(参见15.3.1节)来确定,因此类似的规则也同样适用于set-group-ID程序,并且可以使用相应的组ID调用来避免此类问题的发生。(严格来讲,在Linux上,新文件的所有者是由进程的文件系统用户ID来确定的,这个ID值通常与进程的有效用户ID值是一样的,具体可参见9.5节)。
  • 如果一个set-user-ID-root程序必须要创建一个一开始由其自己拥有但最终由另一个用户拥有的文件,那么所创建的文件在一开始应该不对其他用户开放写权限,这可以通过向open()传入一个合适的mode参数或在调用open()之前设置进程的umask完成。之后,程序可以使用fchown()修改文件的所有权,然后根据需要使用fchmod()修改文件的权限。这里的关键点是set-user-ID程序应该确保它永远不会创建一个由程序所有者拥有但允许其他用户写入(即使这项权限只开放了一瞬间)的文件。
  • 在打开的文件描述符上检查文件的特性(如在open()之后调用fstat()),而不是检查与一个路径名相关联的特性后再打开文件(如在stat()之后调用open())。后一种方法存在使用时间和检查时间的问题。
  • 如果一个程序必须要确保它自己是文件的创建者,那么在调用open()时应该使用O_EXCL标记。
  • 特权进程应该避免创建或依赖像/tmp这样的公共可写的目录,因为这样程序就容易受到那些试图创建文件名与特权程序预期一致的非授权文件的恶意攻击。一个必须要在某个公共可写的目录中创建文件的程序应该至少要使用诸如mkstemp()之类的函数(参见5.12节)确保这个文件的文件名不会不可预测。