DF-2261 / fix.diff
--- a/sys/bus/cam/cam_xpt.c 2026-10-21 04:27:46.575051812 +0000 +++ b/sys/bus/cam/cam_xpt.c 2026-10-21 04:27:46.575051812 +0000 @@ -1,13 +1,26 @@ } else if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP && (serial_buf->length > 0)) { + u_int8_t serial_len; + + /* + * DF-2261: serial_buf->length is device-controlled + * (up to 255) but serial_num[] holds 251 bytes of + * the 255-byte allocation; unclamped it read past + * the allocation, and serial_num_len > 252 then + * overflowed ccb_getdev.serial_num via + * XPT_GDEV_TYPE. + */ + serial_len = serial_buf->length; + if (serial_len > SVPD_SERIAL_NUM_SIZE) + serial_len = SVPD_SERIAL_NUM_SIZE; have_serialnum = 1; path->device->serial_num = - kmalloc((serial_buf->length + 1), + kmalloc((serial_len + 1), M_CAMXPT, M_INTWAIT); bcopy(serial_buf->serial_num, path->device->serial_num, - serial_buf->length); - path->device->serial_num_len = serial_buf->length; - path->device->serial_num[serial_buf->length] = '\0'; + serial_len); + path->device->serial_num_len = serial_len; + path->device->serial_num[serial_len] = '\0'; } else if (cam_periph_error(done_ccb, 0, \ No newline at end of file --- a/sys/bus/cam/cam_xpt.c 2026-10-21 04:27:46.575051812 +0000 +++ b/sys/bus/cam/cam_xpt.c 2026-10-21 04:27:46.575051812 +0000 @@ -1,5 +1,12 @@ cgd->serial_num_len = dev->serial_num_len; if ((dev->serial_num_len > 0) - && (dev->serial_num != NULL)) + && (dev->serial_num != NULL)) { + u_int8_t copy_len = dev->serial_num_len; + + /* DF-2261: never write past + * ccb_getdev.serial_num[252] */ + if (copy_len > sizeof(cgd->serial_num)) + copy_len = sizeof(cgd->serial_num); bcopy(dev->serial_num, cgd->serial_num, - dev->serial_num_len); \ No newline at end of file + copy_len); + } \ No newline at end of file |