一个fread失败时处理不当引发的crash

最近发现一次web机上的agent程序crash了,通过对日志分析,发现是代码中对fread使用理解有误导致。
agent程序的作用是实时收集web机上的某消息文件,然后转发到消息服务器上。在web请求中业务如果需要发送消息,则会将消息写入消息文件中,消息文件的格式为msg1_len:msg1_data:msg2_len:msg2_data...

//该函数每次从文件中取一条消息 #define MESSAGE_SIZE_LEN 4  bool get_one_msg(FILE *fp, char **msg_buf, uint32_t *msg_buf_len) {       uint32_t msg_len;     if (1 != fread(&msg_len, sizeof(msg_len), 1, fp))    {            return false;     }       msg_len = ntohl(msg_len); //msg_len in network byte order     char *msg_buf = (char *)malloc(msg_len + MESSAGE_SIZE_LEN);     if (p == NULL)    {           return false;     }     memcpy(*msg_buf, &net_msg_len, MESSAGESET_SIZE_LEN);     if (1 != fread(*msg_buf + MESSAGE_SIZE_LEN, msg_len, 1, fp))    {           free(*msg_buf);         *msg_buf = NULL;         return false;     }      *msg_buf_len = msg_len + MESSAGE_SIZE_LEN;     return true; }

在上面的代码中,如果另外一个进程正在写消息文件,但只写了消息长度(假定消息为200字节),消息内容还未写完,那么此时调用get_one_msg函数时,会从文件中读取了该消息的长度200字节。接着在执行第二个fread读内容时读取失败,fread返回为0(也许读了20字节就到了文件结尾),但当前文件的偏移量已向前移动。

当下次调用该函数获取消息时,文件偏移量已不在正确的消息边界上了,此时读出的msg_len为4294967295。 由于没有msg_len进行判断,在malloc时,msg_len + 4,实际结果为3。则在memcpy或者每二个fread时就出现了crash 在这优代码中至少有两个地方处理不当: 1 fread失败后,要么把文件offset向前移到之前正确的位置,或者将当前的已读的buffer保存,下次再接着去读余下的。 2 未对msg_len进行检测


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值