仅在打开编译器优化的情况下,某些位置的缓冲区溢出

时间:2015-07-24 18:41:30

标签: c++ c linux makefile compiler-optimization

所以我遇到一个问题,即某段代码给了我这个错误*** BUFFER OVERFLOW DETECTED ***。一旦我打开某些编译器优化选项(这不是我的程序,所以我必须使用这些),这才开始发生。我把它缩小到了哪个选项。我还找到了一种方法来阻止缓冲区溢出,但是,我在程序的另一部分中有非常相似的代码,当我离开它时,不会给我同样的错误。这让我非常困惑,对我的修复非常不自信,所以一些指导将不胜感激。

以下是makefile

的优化选项
CXXFLAGS+=-Os -O2 -fomit-frame-pointer 
CXXFLAGS+=-fno-aggressive-loop-optimizations

我已将其缩小到导致错误的-O2标志。

只有在指定了realpath()标志时,这个函数才会在-O2上的缓冲区溢出失败

static std::string getRealTargetPath (std::string baseTarget)
    {
    char nextTargetLink[MAXPATHLEN];
    memset (nextTargetLink, 0, MAXPATHLEN);

    if (realpath (baseTarget.c_str(), nextTargetLink) == NULL)
        return "";
    else
       //etc...
    }

如果我将MAXPATHLEN(大小1024)更改为PATH_MAX(大小为4096),则上述函数将按预期运行。好,可以。但是,在使用相同 std::string baseTarget之后,以下代码片段执行~20行。

char realLinkPath[MAXPATHLEN];
memset (realLinkPath, 0, MAXPATHLEN);

do
    {         
    if (realpath (linkPath.c_str(), realLinkPath) != NULL)
        if (strcmp(linkPath.c_str(), realLinkPath) != 0)
            return true;

    size_t eraseFrom = linkPath.rfind('/');
    if (std::string::npos != eraseFrom)
        linkPath.erase(eraseFrom);
    } while ( !linkPath.empty() );

总之,即使这两个realpath函数使用相同的const char* path变量,如果缓冲区长度不是PATH_MAX而第二个不是-O2,那么第一个将失败,这一切都是仅在为编译指定C标志时才会发生。

任何帮助都将不胜感激,谢谢。

编辑:正如用户指出的那样,我也将其标记为C,因为该程序非常陈旧,核心是用C++编写的,我将它保留为C尽可能不使用 许多 Person person = new Person("Bob",new LocalDate(1900,02,22)); ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JodaModule()); mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); String json = mapper.writer().writeValueAsString(person); Person returnPojo = mapper.readValue(json, Person.class); System.out.print(returnPojo); 功能

2 个答案:

答案 0 :(得分:5)

嗯,第二部分有不同的输入,所以碰巧偶然realpath()是一个非常破碎的函数,即使是manpage个状态(参见 BUGS )。

你能做的最好的事情就是重新编写代码,以便用null指针作为第二个参数来调用realpath,并注意你返回的分配缓冲区是free() d

答案 1 :(得分:2)

realpath的手册页指定resolved_path的长度必须至少为PATH_MAX。如果realpath的结果是长度超过1024字节的字符串,并且您的缓冲区不够大,则调用undefined behavior。这意味着崩溃可能(如第一种情况)或可能不会(如第二种情况)发生。