遇到问题
前段时间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, &