sizeof 越界 引发的程序崩溃
问题描述
这是几年前在工作中遇到的问题,当时记录在个人笔记中,在无意中翻阅笔记时,发现这个问题很经典,应该很多人会有过类似的问题,所以决定把它分享出来,避免其它人犯类似的错误。
硬件平台:imx6solo
系统:linux 3.0.15
在设备中接入扫码枪时,每次插拔会导致程序崩溃。
相关代码
开辟一个线程处理扫码枪的数据
m_fd = open(SCANNER_DEV, O_RDONLY);//打开usb扫描枪设备
if (m_fd < 0)
{
qDebug("can not open device usbscanner!\n");
}
int r=0;
while (!m_quit)
{
if(m_fd>=0)
{
FD_ZERO(&rdfs);
FD_SET(m_fd, &rdfs);
r = select(m_fd + 1, &rdfs, NULL, NULL, NULL);
if(m_quit)
break;
if(FD_ISSET(m_fd,&rdfs))
{
int size = read(m_fd,&ev,sizeof(ev) );
if(size >= sizeof(struct input_event))
{
dataprocess(ev,size);
}
else if(size<sizeof(struct input_event))
{
close(m_fd);
m_fd = -1;
m_data.clear();
m_transfer.clear();
qDebug()<<Q_FUNC_INFO<<"read fail!!";
}
}
switch(errno)
{
case EIO:
case ENODEV:
{
if(m_fd)
{
close(m_fd);
m_fd = -1;
}
m_data.clear();
m_transfer.clear();
}
qDebug()<<Q_FUNC_INFO<<"select fail"<<"errno="<<int(errno);
break;
}
}
else
{
msleep(500);
if(QFile::exists(SCANNER_DEV))
{
m_fd = open(SCANNER_DEV, O_RDONLY);
m_data.clear();
m_transfer.clear();
}
}
qApp->processEvents();
}
void CommonScannerDev::dataprocess(struct input_event* ev ,int size)
{
for (int i = 0; i < size / sizeof(struct input_event); i++)
{
...
}
...
}
原因分析
当拔下扫码枪时read会出错,返回-1,sizeof 为unsigned 型的,所以int 类型的size/sizeof(xxxx) 时会把size隐性转化成unsigned(同理size >= sizeof(struct input_event)也一样)。所以导致size为-1时调用 dataprocess 函数for循环出现越界,导致程序崩溃。