snprintf或vsnprintf更好,我怎样才能确保我安全地使用它们?

pet*_*Foo 3 c printf buffer-overflow

我决定在一些旧代码上运行一个静态分析工具,我找到了一些我正在使用sprintf的地方.该工具建议使用vsnprintf或snprintf替换调用,因为sprintf不会对缓冲区溢出执行任何类型的边界检查.

我可以轻松地在调用上进行查找和替换,以便它使用snprintf或vsnprintf,但我想确保没有其他任何事情需要完成才能使功能安全

在某些情况下,使用的字符串源自用户输入,在某些情况下,它们不会.

有人对如何做到这一点有任何建议吗?

Dav*_*son 5

我可以轻松地在调用上进行查找和替换,以便它使用snprintf或vsnprintf

不,这并不容易.只要看一下snprintfor 的定义,vsnprintf你就会发现它们采用了一个额外的参数size来指定输出缓冲区的长度.这就是n函数名中的含义.为了使您的代码安全,您必须查看您正在执行sprintf的每个位置,找出可以安全写入输出缓冲区的最大字节数,并将该数字作为size参数传递给snprintfvsnprintf.

不安全的代码:

char buffer[10];
sprintf(buffer, "%d %d", x, y);  // UNSAFE if x and y can be large
Run Code Online (Sandbox Code Playgroud)

等效安全代码:

char buffer[10];
snprintf(buffer, sizeof(buffer), "%d %d", x, y);
Run Code Online (Sandbox Code Playgroud)

也许如果您的所有代码都符合上述示例,那么您可以进行搜索和替换.但对于更复杂的案例,你可能不得不考虑它.

  • 当`buffer`是指针而不是数组时,搜索和替换将无法做正确的事情,但除非你使用的缓冲区小于指针的大小(通常是4或8个字节),否则这只会导致您的输出被过度截断而不是允许溢出.并且希望一旦运行测试,这种截断错误就会立即显现出来. (2认同)