C/C++格式化输出(printf、fprintf、sprintf、syslog等)的不安全用法

本文探讨了C/C++中使用printf、fprintf、sprintf和syslog等格式化输出函数时,由于%n引起的内存安全问题。当format字符串包含%n而无后续参数时,可能导致非法内存访问或内存篡改,从而引发程序崩溃或逻辑错误。通过示例代码分析了可变参数的传递方式,并提出了安全的格式化输出方法,即对字符串进行转义以避免特殊字符被解析。
摘要由CSDN通过智能技术生成

遇到问题

前段时间gameserver突然挂掉,查看coredump发现挂掉的位置是调用syslog,代码如下:

syslog(LOG_INFO, pszLog);

pszLog是日志的内容,当时的那局游戏中恰好有一个玩家叫做fcc%nn,而%n在C/C++格式化输出中代表的是将输出字符串到%n为止的所有字符byte数存放到一处内存中。例如:

int a;
printf("abc%ndef\n", &a);
printf("%d\n", a);

Output:
abcdef
3

刚才的那个syslog语句在输出这次对局信息时包含fcc%nn玩家的名字,等价于下面的代码:

syslog(LOG_INFO, "xxxxx fcc%nn xxxxx");

这个syslog语句并没有在之后跟着任何参数,那么这个%n会输出到某处内存上,服务器挂掉的时候收到的信号是SIGSEGV,说明访问了非法的地址,但是并不是打这条日志服务器都会挂掉,说明很多时候这个%n被输出到了一个进程合法的地址上,导致某处合法内存被修改。这种情况比进程挂掉还要可怕,因为被篡改的内存可能是和打日志完全不想干的功能,导致运行到那个功能的时候出现宕机或者是其他逻辑错误,那时根本不知道是由于这个syslog造成的。

深入研究

我想探究一下如果format字符串中含有%n,而后面没有跟任何参数时,%n的输出究竟会被输出到哪块内存上。

printf("abc%ndef\n")
syslog(LOG_INFO, &
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值