使用更安全的C字符串操纵

ZDNet软件频道 时间:2004-11-03 作者:Builder.com |  我要评论(10)
本文关键词:cpptips DannyKalev
声明在 中的标准 C 函数是由于缓冲区溢出所引发的缺陷(bug)和安全漏洞的丰富来源。虽然推荐的解决方案是迁移到 C++ 的 库,但是并不是所有的程序都可以这样迁移。
本文译自Builder.com,未经许可请勿转载

声明在<cstring> 和<cstdio> 中的标准 C 函数是由于缓冲区溢出所引发的缺陷(bug)和安全漏洞的丰富来源。虽然推荐的解决方案是迁移到 C++ 的<string> 和<sstream> 库,但是并不是所有的程序都可以这样迁移。

通过对很多流行的应用程序和操作系统的与安全相关的缺陷的研究发现,C 字符串函数的应用比我们想象的要多。这个技巧将向你展示如何轻易地提高你的代码安全级别,即使代码中使用了标准 C 函数。

C99 标准 包括了一些明确检查了缓冲区大小的新函数,因此降低了出现溢出的机会。考虑以下有缺陷的例子:

void f(const char *p)
{
  char buf[11]=;
  sprintf(buf,"%10s",p); //very dangerous
  printf("%s ",buf);
}

不要让格式标记“%10s”误导你。如果 p 的长度大于10个字符,那么sprintf() 的写操作就会越过 buf 的边界,从而产生一个缓冲区溢出。

f("hello world!"); //12 characters + nul

检测这类缺陷并不容易,因为它们只在 p 的长度大于10个字符的时候才会发生。黑客通常利用这类脆弱的代码来入侵看上去安全的系统。要修正这一缺陷,可以使用函数snprintf() 代替函数sprintf(),函数snprintf() 的原型为:

int
snprintf(char* buf, size_t maxlen, const char* fmt, ...);

第二个参数定义能被写到 buf 中的字符的最大个数,不考虑格式标志以及源字符串的大小:

snprintf(buf, 10, "%10s",p); //now safe
f("hello world!"); //string is chopped to "hello worl"

相似的,使用strncpy()、strncmp()、strncat()、strnicmp() 和 strnset() 相应地代替strcmp()、strcat()、stricmp() 和 strset()。例如:

const int LINE_SIZE=81;
char buf[LINE_SIZE]=;
  // write up to 80 chars to buf:
strncpy(buf, dest, LINE_SIZE-1);
  // compare no more than 80 chars:
int equal= strncmp(buf, dest, LINE_SIZE-1);

使用缓冲区大小有限制的 C 函数版本可以降低缓冲区溢出发生的可能性,也不要求对原始代码进行实质的变化。


本文作者:Danny Kalev 是一位具有14年经验的系统分析家、软件工程师,尤其擅长C++ 和面向对象设计。


责任编辑:李宁

欢迎评论投稿

百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134