if (copy_to_user(cmd_in, buf, outlen)) 
if (outlen && copy_to_user(cmd_in, buf, outlen)) 
int scsi_ioctl_send_command(struct scsi_device *sdev,			    struct scsi_ioctl_command __user *sic){	char *buf;	unsigned char cmd[MAX_COMMAND_SIZE];	unsigned char sense[SCSI_SENSE_BUFFERSIZE];	char __user *cmd_in;	unsigned char opcode;	unsigned int inlen, outlen, cmdlen;	unsigned int needed, buf_needed;	int timeout, retries, result;	int data_direction;	gfp_t gfp_mask = GFP_KERNEL;	if (!sic)		return -EINVAL;	if (sdev->host->unchecked_isa_dma)		gfp_mask |= GFP_DMA;	/*	 * Verify that we can read at least this much.	 */	if (!access_ok(VERIFY_READ, sic, sizeof(Scsi_Ioctl_Command)))		return -EFAULT;	if(__get_user(inlen, &sic->inlen))		return -EFAULT;			if(__get_user(outlen, &sic->outlen))		return -EFAULT;	/*	 * We do not transfer more than MAX_BUF with this interface.	 * If the user needs to transfer more data than this, they	 * should use scsi_generics (sg) instead.	 */	if (inlen > MAX_BUF)		return -EINVAL;	if (outlen > MAX_BUF)		return -EINVAL;	cmd_in = sic->data;	if(get_user(opcode, cmd_in))		return -EFAULT;	needed = buf_needed = (inlen > outlen ? inlen : outlen);	if (buf_needed) {		buf_needed = (buf_needed + 511) & ~511;		if (buf_needed > MAX_BUF)			buf_needed = MAX_BUF;		buf = kmalloc(buf_needed, gfp_mask);		if (!buf)			return -ENOMEM;		memset(buf, 0, buf_needed);		if (inlen == 0) {			data_direction = DMA_FROM_DEVICE;		} else if (outlen == 0 ) {			data_direction = DMA_TO_DEVICE;		} else {			/*			 * Can this ever happen?			 */			data_direction = DMA_BIDIRECTIONAL;		}	} else {		buf = NULL;		data_direction = DMA_NONE;	}	/*	 * Obtain the command from the user's address space.	 */	cmdlen = COMMAND_SIZE(opcode);		result = -EFAULT;	if (!access_ok(VERIFY_READ, cmd_in, cmdlen + inlen))		goto error;	if(__copy_from_user(cmd, cmd_in, cmdlen))		goto error;	/*	 * Obtain the data to be sent to the device (if any).	 */	if(copy_from_user(buf, cmd_in + cmdlen, inlen))		goto error;	switch (opcode) {	case SEND_DIAGNOSTIC:	case FORMAT_UNIT:		timeout = FORMAT_UNIT_TIMEOUT;		retries = 1;		break;	case START_STOP:		timeout = START_STOP_TIMEOUT;		retries = NORMAL_RETRIES;		break;	case MOVE_MEDIUM:		timeout = MOVE_MEDIUM_TIMEOUT;		retries = NORMAL_RETRIES;		break;	case READ_ELEMENT_STATUS:		timeout = READ_ELEMENT_STATUS_TIMEOUT;		retries = NORMAL_RETRIES;		break;	case READ_DEFECT_DATA:		timeout = READ_DEFECT_DATA_TIMEOUT;		retries = 1;		break;	default:		timeout = IOCTL_NORMAL_TIMEOUT;		retries = NORMAL_RETRIES;		break;	}	result = scsi_execute(sdev, cmd, data_direction, buf, needed,			      sense, timeout, retries, 0);	/* 	 * If there was an error condition, pass the info back to the user. 	 */	if (result) {		int sb_len = sizeof(*sense);		sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len;		if (copy_to_user(cmd_in, sense, sb_len))			result = -EFAULT;	} else {		if (copy_to_user(cmd_in, buf, outlen))			result = -EFAULT;	}	error:	kfree(buf);	return result;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/4647722673994787bfa294a163fcb6955b93d417/scsi_ioctl.c/buggy/drivers/scsi/scsi_ioctl.c