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

amz*_*mza 0 c c++ linux makefile compiler-optimization

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

以下是来自的优化选项 makefile

CXXFLAGS+=-Os -O2 -fomit-frame-pointer 
CXXFLAGS+=-fno-aggressive-loop-optimizations
Run Code Online (Sandbox Code Playgroud)

我把它缩小到-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...
    }
Run Code Online (Sandbox Code Playgroud)

如果我将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() );
Run Code Online (Sandbox Code Playgroud)

总而言之,即使这两个realpath函数使用相同的const char* path变量,如果缓冲区不是PATH_MAX长度而第二个函数不是长度,第一个函数将失败,但只有在-O2为编译指定了标志时才会发生这种情况.

任何帮助将不胜感激,谢谢.

编辑:作为一个用户指出的那样,我也标记这是C因为该计划是非常老的核心是写在C它的首选,我把它作为C要尽可能不使用太多的许多C++功能

小智 5

那么,第二部分具有不同的输入,所以它发生在很好地工作意外.realpath()是一个真正破碎的功能,即使是手册页也指出(参见BUGS).

您可以做的最好的事情是重新编写代码,因此使用null指针作为第二个参数调用realpath,并注意您返回的已分配缓冲区是否free()正确