MTK平台典型问题分享(数组越界,内存被踩坏)

今天分析了一个用户投诉的问题,这里再记录一下,順便整理一下思路

用户投诉的问题操作步骤为:

1,进音乐播放器

2,按功能中间键的播放键→选项→音乐管理→确定→按功能上翻键,就会出现死机复位等现象。

从拿到的复位信息来看,只能看到复位里堆栈中函数调用情况如下:

异常类型: 数据访问中止异常(DATAABORT_EXCEPTION)
复位序号: 1
软件版本: D1008_A_1.15
启动模式: 普通模式(NORMAL_BOOT)
复位时间: 12/01/02 00:18:40 01 (YY/MM/DD HH:NN:SS WD)
复位模块: MMIMMI
复位模块状态: 就绪(READY)
栈指针: 0xf1def498
复位时栈的内容, 保存了复位时所调用函数的地址:
[字段说明: 内容 : 匹配符号: 名称, 地址, (内容的地址偏址)]
  0x50001779 : 匹配符号:     RestoreIRQMask         0x50001778     (+0x00000000)
  0x00219c89 : 匹配符号:     gdi_image_parse_resource_internal         0x00219c7c     (+0x0000000c)
  0x00219bad : 匹配符号:     gdi_image_parse_info         0x00219b58     (+0x00000054)
  0x00216de9 : 匹配符号:     gdi_image_codec_get_dimension         0x00216dc0     (+0x00000028)
  0x00001109
  0x00217b4f : 匹配符号:     gdi_image_get_dimension         0x00217b34     (+0x0000001a)
  0x006e4c13 : 匹配符号:     SKY_gdi_image_get_dimension         0x006e4c0c     (+0x00000006)
  0x00a8d381 : 匹配符号:     sky_ca_list_create         0x00a8d1d4     (+0x000001ac)
  0x000000fd
  0x0083ebdf : 匹配符号:     sky_ca_list_show_static         0x0083ea14     (+0x000001ca)

一般数据访问异常(DATAABORT_EXCEPTION)均为指针地址为空取不到数据,或者指针地址被破坏了取不到数据导致的。

经过分析认为:

在 MTK 解析音乐文件的接口中,艺术家字段会有80个字符的长度。
#define MAX_ID3_ARTIST_LEN 80 ,而将该字段写入到 第三方斯凯的 接口中最大只能写 32 个字符的长度。
#define SKY_CA_CLIST_ITEM_MAX_HINT_STR_LENGTH (32)
在 mmi_audply_playlist_hint_get_artist_bbk 函数中传参的时候也没有作长度限制,直接使用了如下语句
mmi_ucs2cpy((S8 *)hint_array[0], (const S8 *)daf_info_p->artist);

这一般也不会有什么问题,因为一般艺术家字段没有那么长。故长时间以来也没有发现这个隐藏的问题。

今天投诉的音乐文件中有一个艺术家字段超长的音乐。其中艺术家字段如下:
“谭晶&陈奕迅&容祖儿&光良&莫文蔚&古巨基&李宇春&张杰&蔡卓妍&韩磊&陈明&宋雪莱&江若琳”总长度有46个字符。超过了斯凯规定的 32 个字符。
故导致结构体内部数组越界。其中结构体是这样定义的。

/*列表项结构体*/
typedef struct
{
kal_uint8* icon_ptr; /*list item 前面的icon*/
kal_uint16 string[SKY_CA_CLIST_ITEM_MAX_STRING_LENGTH+2]; /*list item string*/
kal_uint16 hint_str[SKY_CA_CLIST_ITEM_MAX_HINT_STR_LENGTH+2]; /*list item hint string*/
kal_uint32 flag; /*标记位,SKY_CA_CLIST_ITEM_MARKED 已标记,SKY_CA_CLIST_ITEM_UNMARKED 未标记*/
}SKY_CA_CLIST_ITEM;

由于这个结构体是在创建音乐列表的时候循环读取的。故造成下一个结构体数组项的 kal_uint8* icon_ptr 数据被踩坏。

而在复位栈信息中最后调用的那个函数确实是在解析图片时出了问题,即从传给该 gdi_image_parse_resource_internal 函数的参数处取不到数据导致复位。

改善方案及措施:
一开始,认为只需要将 SKY_CA_CLIST_ITEM_MAX_HINT_STR_LENGTH 宏改大为 80 个字符即可,这样改是不会复位了,但是改了以后发现 后面一个字段 kal_uint32 flag; /*标记位,SKY_CA_CLIST_ITEM_MARKED 已标记,SKY_CA_CLIST_ITEM_UNMARKED 未标记*/ 又被踩掉了,结果导致在列表中无法标记音乐文件。认为是斯凯在内部代码上没有做好扩展导致的,但斯凯内部的函数实现我们都看不到,也没办法继续改了。

后面只好限制读取艺术家字段的长度为 32,与斯凯接口提供的最大长度相稳合。即
                mmi_ucs2ncpy((S8 *)hint_array[0], (const S8 *)daf_info_p->artist, SKY_CA_CLIST_ITEM_MAX_HINT_STR_LENGTH);
经验证,这样改可以解决问题。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值