Fix several potential buffer overrun conditions. These changes have been
tested both in the kernel and in userland. Also, fix a couple of printf warnings that show up when CAMDEBUG is defined. Reviewed by: imp Partially submitted by: imp
This commit is contained in:
parent
999b2a26da
commit
3263ebd2ec
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: cam_xpt.c,v 1.22 1998/10/14 22:51:51 ken Exp $
|
* $Id: cam_xpt.c,v 1.23 1998/10/15 17:46:18 ken Exp $
|
||||||
*/
|
*/
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
@ -2596,7 +2596,7 @@ xpt_action(union ccb *start_ccb)
|
|||||||
scsi_op_desc(start_ccb->csio.cdb_io.cdb_bytes[0],
|
scsi_op_desc(start_ccb->csio.cdb_io.cdb_bytes[0],
|
||||||
&path->device->inq_data),
|
&path->device->inq_data),
|
||||||
scsi_cdb_string(start_ccb->csio.cdb_io.cdb_bytes,
|
scsi_cdb_string(start_ccb->csio.cdb_io.cdb_bytes,
|
||||||
cdb_str)));
|
cdb_str, sizeof(cdb_str))));
|
||||||
/* FALLTRHOUGH */
|
/* FALLTRHOUGH */
|
||||||
}
|
}
|
||||||
case XPT_TARGET_IO:
|
case XPT_TARGET_IO:
|
||||||
@ -3256,7 +3256,7 @@ xpt_run_dev_allocq(struct cam_eb *bus)
|
|||||||
device = qinfo->device;
|
device = qinfo->device;
|
||||||
|
|
||||||
CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
|
CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
|
||||||
("running device 0x%x\n", device));
|
("running device %p\n", device));
|
||||||
|
|
||||||
drvq = &device->drvq;
|
drvq = &device->drvq;
|
||||||
|
|
||||||
@ -3350,7 +3350,7 @@ xpt_run_dev_sendq(struct cam_eb *bus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
|
CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE,
|
||||||
("running device 0x%x\n", device));
|
("running device %p\n", device));
|
||||||
|
|
||||||
work_ccb = cam_ccbq_peek_ccb(&device->ccbq, 0);
|
work_ccb = cam_ccbq_peek_ccb(&device->ccbq, 0);
|
||||||
if (work_ccb == NULL) {
|
if (work_ccb == NULL) {
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* $Id: scsi_all.c,v 1.4 1998/09/29 22:11:30 ken Exp $
|
* $Id: scsi_all.c,v 1.5 1998/10/02 21:00:54 ken Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
@ -1560,7 +1560,7 @@ scsi_error_action(int asc, int ascq, struct scsi_inquiry_data *inq_data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string)
|
scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string, size_t len)
|
||||||
{
|
{
|
||||||
u_int8_t cdb_len;
|
u_int8_t cdb_len;
|
||||||
char holdstr[8];
|
char holdstr[8];
|
||||||
@ -1610,6 +1610,13 @@ scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string)
|
|||||||
*cdb_string = '\0';
|
*cdb_string = '\0';
|
||||||
for (i = 0; i < cdb_len; i++) {
|
for (i = 0; i < cdb_len; i++) {
|
||||||
sprintf(holdstr, "%x ", cdb_ptr[i]);
|
sprintf(holdstr, "%x ", cdb_ptr[i]);
|
||||||
|
/*
|
||||||
|
* If we're about to exceed the length of the string,
|
||||||
|
* just return what we've already printed.
|
||||||
|
*/
|
||||||
|
if (strlen(holdstr) + strlen(cdb_string) > len)
|
||||||
|
break;
|
||||||
|
|
||||||
strcat(cdb_string, holdstr);
|
strcat(cdb_string, holdstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1672,12 +1679,14 @@ scsi_sense_print(struct ccb_scsiio *csio)
|
|||||||
printf("%s. CDB: %s\n",
|
printf("%s. CDB: %s\n",
|
||||||
scsi_op_desc(csio->cdb_io.cdb_ptr[0],
|
scsi_op_desc(csio->cdb_io.cdb_ptr[0],
|
||||||
&cgd.inq_data),
|
&cgd.inq_data),
|
||||||
scsi_cdb_string(csio->cdb_io.cdb_ptr, cdb_str));
|
scsi_cdb_string(csio->cdb_io.cdb_ptr, cdb_str,
|
||||||
|
sizeof(cdb_str)));
|
||||||
} else {
|
} else {
|
||||||
printf("%s. CDB: %s\n",
|
printf("%s. CDB: %s\n",
|
||||||
scsi_op_desc(csio->cdb_io.cdb_bytes[0],
|
scsi_op_desc(csio->cdb_io.cdb_bytes[0],
|
||||||
&cgd.inq_data), scsi_cdb_string(
|
&cgd.inq_data), scsi_cdb_string(
|
||||||
csio->cdb_io.cdb_bytes, cdb_str));
|
csio->cdb_io.cdb_bytes, cdb_str,
|
||||||
|
sizeof(cdb_str)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1809,7 +1818,7 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
char path_str[64];
|
char path_str[64];
|
||||||
char tmpstr[2048];
|
char tmpstr[2048];
|
||||||
int tmpstrlen = 2048;
|
int tmpstrlen = 2048;
|
||||||
int cur_len = 0, retlen;
|
int cur_len = 0, tmplen = 0, retlen;
|
||||||
|
|
||||||
if ((device == NULL) || (csio == NULL) || (str == NULL))
|
if ((device == NULL) || (csio == NULL) || (str == NULL))
|
||||||
return(NULL);
|
return(NULL);
|
||||||
@ -1836,23 +1845,34 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
|
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "%s", path_str);
|
retlen = snprintf(tmpstr, tmpstrlen, "%s", path_str);
|
||||||
|
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
if ((tmplen = str_len - cur_len - 1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
|
|
||||||
if ((csio->ccb_h.flags & CAM_CDB_POINTER) != 0) {
|
if ((csio->ccb_h.flags & CAM_CDB_POINTER) != 0) {
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "%s. CDB: %s\n",
|
retlen = snprintf(tmpstr, tmpstrlen, "%s. CDB: %s\n",
|
||||||
scsi_op_desc(csio->cdb_io.cdb_ptr[0],
|
scsi_op_desc(csio->cdb_io.cdb_ptr[0],
|
||||||
&device->inq_data),
|
&device->inq_data),
|
||||||
scsi_cdb_string(csio->cdb_io.cdb_ptr,
|
scsi_cdb_string(csio->cdb_io.cdb_ptr,
|
||||||
cdb_str));
|
cdb_str,
|
||||||
|
sizeof(cdb_str)));
|
||||||
} else {
|
} else {
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "%s. CDB: %s\n",
|
retlen = snprintf(tmpstr, tmpstrlen, "%s. CDB: %s\n",
|
||||||
scsi_op_desc(csio->cdb_io.cdb_bytes[0],
|
scsi_op_desc(csio->cdb_io.cdb_bytes[0],
|
||||||
&device->inq_data), scsi_cdb_string(
|
&device->inq_data), scsi_cdb_string(
|
||||||
(u_int8_t *)&csio->cdb_io.cdb_bytes, cdb_str));
|
csio->cdb_io.cdb_bytes, cdb_str,
|
||||||
|
sizeof(cdb_str)));
|
||||||
}
|
}
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len - 1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1886,8 +1906,13 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
|
|
||||||
|
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "%s", path_str);
|
retlen = snprintf(tmpstr, tmpstrlen, "%s", path_str);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len - 1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
|
|
||||||
error_code = sense->error_code & SSD_ERRCODE;
|
error_code = sense->error_code & SSD_ERRCODE;
|
||||||
sense_key = sense->flags & SSD_KEY;
|
sense_key = sense->flags & SSD_KEY;
|
||||||
@ -1895,15 +1920,25 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
switch (error_code) {
|
switch (error_code) {
|
||||||
case SSD_DEFERRED_ERROR:
|
case SSD_DEFERRED_ERROR:
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "Deferred Error: ");
|
retlen = snprintf(tmpstr, tmpstrlen, "Deferred Error: ");
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len - 1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
/* FALLTHROUGH */
|
/* FALLTHROUGH */
|
||||||
case SSD_CURRENT_ERROR:
|
case SSD_CURRENT_ERROR:
|
||||||
|
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "%s",
|
retlen = snprintf(tmpstr, tmpstrlen, "%s",
|
||||||
scsi_sense_key_text[sense_key]);
|
scsi_sense_key_text[sense_key]);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len - 1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
|
|
||||||
info = scsi_4btoul(sense->info);
|
info = scsi_4btoul(sense->info);
|
||||||
|
|
||||||
@ -1919,8 +1954,13 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
retlen = snprintf(tmpstr, tmpstrlen,
|
retlen = snprintf(tmpstr, tmpstrlen,
|
||||||
" req sz: %d (decimal)",
|
" req sz: %d (decimal)",
|
||||||
info);
|
info);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len - 1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (info) {
|
if (info) {
|
||||||
@ -1936,15 +1976,24 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
" info:%x",
|
" info:%x",
|
||||||
info);
|
info);
|
||||||
}
|
}
|
||||||
strncat(str, tmpstr,
|
|
||||||
str_len - cur_len - 1);
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (info) {
|
} else if (info) {
|
||||||
retlen = snprintf(tmpstr, tmpstrlen," info?:%x", info);
|
retlen = snprintf(tmpstr, tmpstrlen," info?:%x", info);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sense->extra_len >= 4) {
|
if (sense->extra_len >= 4) {
|
||||||
@ -1955,8 +2004,13 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
sense->cmd_spec_info[1],
|
sense->cmd_spec_info[1],
|
||||||
sense->cmd_spec_info[2],
|
sense->cmd_spec_info[2],
|
||||||
sense->cmd_spec_info[3]);
|
sense->cmd_spec_info[3]);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1969,15 +2023,25 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
retlen = snprintf(tmpstr, tmpstrlen,
|
retlen = snprintf(tmpstr, tmpstrlen,
|
||||||
" asc:%x,%x\n%s%s", asc, ascq,
|
" asc:%x,%x\n%s%s", asc, ascq,
|
||||||
path_str, desc);
|
path_str, desc);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sense->extra_len >= 7 && sense->fru) {
|
if (sense->extra_len >= 7 && sense->fru) {
|
||||||
retlen = snprintf(tmpstr, tmpstrlen,
|
retlen = snprintf(tmpstr, tmpstrlen,
|
||||||
" field replaceable unit: %x",
|
" field replaceable unit: %x",
|
||||||
sense->fru);
|
sense->fru);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1986,7 +2050,12 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
retlen = snprintf(tmpstr, tmpstrlen, " sks:%x,%x",
|
retlen = snprintf(tmpstr, tmpstrlen, " sks:%x,%x",
|
||||||
sense->sense_key_spec[0],
|
sense->sense_key_spec[0],
|
||||||
scsi_2btoul(&sense->sense_key_spec[1]));
|
scsi_2btoul(&sense->sense_key_spec[1]));
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -1994,21 +2063,38 @@ scsi_sense_string(struct cam_device *device, struct ccb_scsiio *csio,
|
|||||||
default:
|
default:
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "error code %d",
|
retlen = snprintf(tmpstr, tmpstrlen, "error code %d",
|
||||||
sense->error_code & SSD_ERRCODE);
|
sense->error_code & SSD_ERRCODE);
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
|
|
||||||
if (sense->error_code & SSD_ERRCODE_VALID) {
|
if (sense->error_code & SSD_ERRCODE_VALID) {
|
||||||
retlen = snprintf(tmpstr, tmpstrlen,
|
retlen = snprintf(tmpstr, tmpstrlen,
|
||||||
" at block no. %d (decimal)",
|
" at block no. %d (decimal)",
|
||||||
info = scsi_4btoul(sense->info));
|
info = scsi_4btoul(sense->info));
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
retlen = snprintf(tmpstr, tmpstrlen, "\n");
|
retlen = snprintf(tmpstr, tmpstrlen, "\n");
|
||||||
strncat(str, tmpstr, str_len - cur_len - 1);
|
|
||||||
|
if ((tmplen = str_len - cur_len -1) < 0)
|
||||||
|
goto sst_bailout;
|
||||||
|
|
||||||
|
strncat(str, tmpstr, tmplen);
|
||||||
cur_len += retlen;
|
cur_len += retlen;
|
||||||
|
str[str_len - 1] = '\0';
|
||||||
|
|
||||||
|
sst_bailout:
|
||||||
|
|
||||||
return(str);
|
return(str);
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||||
*
|
*
|
||||||
* $Id: scsi_all.h,v 1.3 1998/09/29 22:11:30 ken Exp $
|
* $Id: scsi_all.h,v 1.4 1998/10/02 05:25:49 ken Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -709,7 +709,8 @@ int scsi_interpret_sense(struct cam_device *device,
|
|||||||
|
|
||||||
const char * scsi_op_desc(u_int16_t opcode,
|
const char * scsi_op_desc(u_int16_t opcode,
|
||||||
struct scsi_inquiry_data *inq_data);
|
struct scsi_inquiry_data *inq_data);
|
||||||
char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string);
|
char * scsi_cdb_string(u_int8_t *cdb_ptr, char *cdb_string,
|
||||||
|
size_t len);
|
||||||
|
|
||||||
void scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
|
void scsi_print_inquiry(struct scsi_inquiry_data *inq_data);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user