istream 的tellg/seekg 无法防止堆栈粉碎(g++)?

Posted

技术标签:

【中文标题】istream 的tellg/seekg 无法防止堆栈粉碎(g++)?【英文标题】:istream's tellg/seekg cannot be protected from stack smashing (g++)? 【发布时间】:2011-06-19 08:49:33 【问题描述】:

对于我正在编写的程序,计算文件大小对我很有用,我使用 iostream 的 tellg 和 seekg 函数来计算,但这会导致 -Wstack-protector 发出警告。以下代码重现了“问题”:

#include <iostream>

std::streamsize get_file_size(std::ifstream& ifs)  // line 12 (in warning, below)
  const std::streamsize start = ifs.tellg();
  ifs.seekg(0,std::ios::end);
  const std::streamsize end = ifs.tellg();
  ifs.seekg(start);
  return (end-start);

g++(标志:-fstack-protector -Wstack-protector,编译器版本:4.4.3 (Ubuntu 4.4.3-4ubuntu5),系统: Ubuntu 10.04 x86_64) 给出警告:

f.cc:在函数“std::streamsize get_file_size(std::ifstream&)”中: f.cc:12:警告:没有保护功能:没有至少 8 个字节长的缓冲区

(当我使用直接从 GNU 下载和编译的 GCC 4.5.2 时,我得到了相同的结果。)

这是从堆栈粉碎保护的工作方式(通常或通过 GCC)和/或 ifstream 和 seekg/tellg 的工作方式中预期的吗?如果是这样,这个警告不能被忽略还是有更好的办法?

编辑

实际上,上面的一些代码是多余的。只是为了澄清发生了什么:

#include <iostream>

void f1(std::ifstream& ifs)  // line 6
    ifs.tellg();


void f2(std::ifstream& ifs)  // line 10
    // call seekg(std::streampos)
    ifs.seekg(0);


void f3(std::ifstream& ifs) 
    // call seekg(std::streamoff, std::ios_base::seekdir)
    ifs.seekg(0,std::ios::beg);

导致 g++(与上述规格相同)警告:

main.cc:在函数‘void f1(std::ifstream&)’中: main.cc:6:警告:没有保护功能:没有至少 8 个字节长的缓冲区 main.cc:在函数‘void f2(std::ifstream&)’中: main.cc:10:警告:没有保护功能:没有至少 8 个字节长的缓冲区

有趣的是,f3 不会触发警告。

【问题讨论】:

【参考方案1】:

你可能不想看到this.

一般建议是你真的不应该关心,特别是在你的情况下,当你不分配任何可用于执行缓冲区的内部缓冲区时溢出攻击。

【讨论】:

感谢您的链接(尽管我认为是阅读该页面导致我将 -Wstack-protector 包含在我的程序构建中!)。我没有在get_file_size 中放置任何可以被利用的缓冲区这一事实是我问这个问题的原因:为什么还会出现警告?即使我可以在实践中忽略它,为了我的利益,我仍然希望了解正在发生的事情。 @Zorawar 好吧,我不擅长实际的缓冲区溢出技术,所以我想我们将不得不等待具有特定技能的人来解释这可以或可以如何'不要被利用) 也许我应该通过提及我在一个名为“NSA Project X 类人语言翻译器”的文件中找到代码来促进参与? (开个玩笑美国国家安全局!它来自军情六处......)

以上是关于istream 的tellg/seekg 无法防止堆栈粉碎(g++)?的主要内容,如果未能解决你的问题,请参考以下文章

C++流输入istream的成员函数及其用法

从函数返回 istream 的正确方法

IStream 接口

istream_iterator && istream_iteratorbuf

使用 IStream 打开文件

将 QT 资源转换为 ::std::istream&