[smartmontools-support] smartctl cciss segfault crash

Michal Hlavinka mhlavink at redhat.com
Tue Nov 19 18:11:38 CET 2019


Hi,

one of our users with hpe proliant g10 sees smartctl crash once a while. 
I was able to check the core file and found a problem:

(gdb) bt
#0  __memcpy_ssse3_back () at
../sysdeps/x86_64/multiarch/memcpy-ssse3-back.S:1844
#1  0x0000564d81bab2f0 in memcpy (__len=<optimized out>,
__src=0x7ffff4f10120, __dest=<optimized out>) at
/usr/include/bits/string3.h:51
#2  cciss_io_interface (device=3, target=1, iop=0x7ffff4f103d0,
report=0) at cciss.cpp:96
#3  0x0000564d81ba2b4d in
os_linux::linux_cciss_device::scsi_pass_through (this=0x564d8275a420,
iop=<optimized out>) at os_linux.cpp:1536
#4  0x0000564d81b908f3 in sat::sat_device::scsi_pass_through
(this=0x564d8274f770, iop=<optimized out>) at scsiata.cpp:503
#5  0x0000564d81b8d498 in scsiLogSense
(device=device at entry=0x564d8274f7f0, pagenum=pagenum at entry=0,
subpagenum=subpagenum at entry=255, pBuf=pBuf at entry=0x564d81e01dc0 <gBuf>
"@\377", bufLen=bufLen at entry=16124,
     known_resp_len=known_resp_len at entry=-1) at scsicmds.cpp:588
#6  0x0000564d81b967fa in scsiGetSupportedLogPages
(device=device at entry=0x564d8274f7f0) at scsiprint.cpp:145
#7  0x0000564d81b9d1fb in scsiPrintMain (device=0x564d8274f7f0,
options=...) at scsiprint.cpp:2385
#8  0x0000564d81b5ce4e in main_worker (argc=5, argv=0x7ffff4f134b8) at
smartctl.cpp:1608
#9  0x0000564d81b57865 in main (argc=<optimized out>, argv=<optimized
out>) at smartctl.cpp:1629


cciss.cpp: cciss_io_interface(...) : 96
int cciss_io_interface(int device, int target, struct scsi_cmnd_io * 
iop, int report)
{
    unsigned char pBuf[512] = {0};
...
...
    if (DXFER_FROM_DEVICE == iop->dxfer_dir)
    {
-->   memcpy(iop->dxferp, pBuf, iop->dxfer_len);
       if (report > 1)
              {

where pBuf is a local buffer of 512 bytes
iop->dxfer_len is 16124, it is initialized from pageLen value in 
scsicmds.cpp:scsiLogSense:539:

-->  io_hdr.dxfer_len = pageLen;

int scsiLogSense(scsi_device * device, int pagenum, int subpagenum, 
uint8_t *pBuf, int bufLen, int known_resp_len)

with pageLen being bufLen because known_resp_len < 0 and bufLen = 16124

526: else if (known_resp_len < 0)
527:    pageLen = bufLen;

That is obviously too much as cciss_io_interface uses its own pBuf and 
not the one provided to scsiLogSense and cciss_io_interface's pBuf is 
only 512 bytes thus it crashes.

scsiLogSense gets bufLen as a parameter together with pBuf pointer, in 
this case it comes from

scsiprint.cpp:scsiGetSupportedLogPages:145:
scsiLogSense(device, SUPPORTED_LPAGES, SUPP_SPAGE_L_SPAGE, gBuf, 
LOG_RESP_LONG_LEN, -1)
where gBuf has size 65532 so safe enough for 16124 if it was used and 
not the 512 pBuf version. So it would be enough if buffer pointer was 
passed to cciss_io_interface instead of it using its own small one.

Let me know if you need any more information.

Cheers,
Michal Hlavinka




More information about the Smartmontools-support mailing list