从X.org近期的更新说开

最近, X.org公布了一个栈溢出导致登陆普通用户利用这一漏洞获取超级用户权限的bug, 这个bug已经存在X WINDOW中存在长达22年. 产生bug的代码如下:

char charName[100];
 
.....
 
if (sscanf((char *) line, "STARTCHAR %s", charName) != 1) {
   bdfError("bad character name in BDF file\n");
   goto BAILOUT; /* bottom of function, free and return error */
}

这段代码预先在栈空间上申请100个字节的内存空间charName, 之后用sscanf将line字符串中的对应字段拷贝到charName. 代码中, line字符串读取的内容是用户可以指定的. 不怀好意的用户可以让这个字段的字符数大于100, 这样正在运行的X WINDOW程序栈空间的内容就会被修改, 结果可能导致X Window崩溃; 更坏的结果则是因为X Window程序以超级用户执行, 栈溢出后导致该用户运行他编写的恶意程序后获得系统的root权限. 修补这个漏洞的方法很简单, 只要把在格式输入中的"%s"改成"%99s"即可. 查阅sscanf的帮助文档我们会发现, scanf函数对于字符串输入的中止条件是当遇到空格或者超过"%s"提示的长度. 修改成"%99s"后无论line格式如何, sscanf向charName写入的字符数都不会超过99, 这样就避免了爆栈的发生.

作为为了编写操作系统而发明的C语言, 它与其他那些比它更为高级的编程语言一个明显的不同就是它假定程序员的清楚的知道自己编写的每一条语句在操作系统执行时这个层面上的含义. 有些人认为这是C语言的特点, 有些人认为这是C语言的缺陷. 但无论如何, C程序员必须在编写程序的时候时时刻刻都要考虑自己代码中的每一个变量或指针指向的地址都在什么内存的地方(栈, 堆, 只读数据区等等), 改变指针指向的(往往是一块连续的)地址的值的时候, 是否有足够的空间. 使用C库函数的时候尽量避免使用本身设计不合理的函数(如gets); 自己设计函数的时候, 如果形参是指针, 在函数中还要修改指针指向的内容, 函数参数列表中必须有(显式或隐式)指定指针指向合法地址的长度的参量.

此条目发表在计算机与网络技术分类目录,贴了标签。将固定链接加入收藏夹。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.