TOCTTOU - 在处理文件之前使用访问权限

TOCTTOU - Using access before handling file

我有这个功能,可以将文件复制到镜像目录,然后删除旧的。它运行良好,但在 Coverity 中,我的代码显示为 TOCTTOU 警告。

void function(){
    const char *original_key = "path/to/file/filename";
    const char *mirror_key = "path/to/another/file/filename";

    if((access(original_key, F_OK) == 0) && (access(mirror_key, F_OK) == 0)){
        copy_file("/bin/cp %s %s", original_key, mirror_key); /*copy function in another cpp file*/
        unlink(original_key);
    }
}

/* in another cpp file */
int copy_file(const char*command, ...){
    int rc = -1;
    va_list args;
    char *buffer = NULL;
    va_start(args, command);
    vasprintf(&buffer, command, args);
    va_end(args);
    if (buffer)
    {
        char *wrd;
        char *ptr = buffer;
        std::vector<const char *> list;
        while ((wrd = strsep(&ptr, " ")) != NULL)
        {
            if (strlen(wrd))
            {
                list.push_back(wrd);
            }
        }
        if (list.size() > 0)
        {
            char *argv[list.size() + 1];
            for (size_t idx = 0; idx < list.size(); idx++)
            {
                argv[idx] = (char *)list[idx];
            }
            argv[list.size()] = NULL;
            rc = system_spawn_args(argv);
        }
        free(buffer);
    }
    return(rc);
}

在这种情况下有没有办法防止TOCTTOU?

注意:移动无效 - 跨设备错误。

谢谢

问题可能是典型的 Unix / Linux 使用函数访问的错误。 here 描述了确切的细节,甚至还有一个例子。还有关于如何降低风险的建议。

由于在链接的维基百科文章中描述得很好,我就不再重复了。

并且,由于您的示例中没有 C++ 代码,您可能需要用 C++ 重写代码。此外,您的 "copy-function" 使用系统调用似乎过于复杂。

请考虑重构它。因此,我还建议您在 Whosebug 上阅读一篇关于复制文件的文章 here

如果您的代码是非生产性的并且仅供家庭使用,那么您也可以忽略此消息。

因为我的主要功能基本上是将一个文件移动到另一个文件。我只是使用 rename() 这完成了工作,也没有警告我作为 Coverity

中的 TOCTTOU