NetBSD Problem Report #56109

From reinoud@gorilla.13thmonkey.org  Fri Apr 16 12:44:35 2021
Return-Path: <reinoud@gorilla.13thmonkey.org>
Received: from mail.netbsd.org (mail.netbsd.org [199.233.217.200])
	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))
	(Client CN "mail.NetBSD.org", Issuer "mail.NetBSD.org CA" (not verified))
	by mollari.NetBSD.org (Postfix) with ESMTPS id 1D2EC1A9245
	for <gnats-bugs@gnats.NetBSD.org>; Fri, 16 Apr 2021 12:44:35 +0000 (UTC)
Message-Id: <20210416124431.142B42FF0791@gorilla.13thmonkey.org>
Date: Fri, 16 Apr 2021 14:44:31 +0200 (CEST)
From: reinoud@NetBSD.org
Reply-To: reinoud@gorilla.13thmonkey.org
To: gnats-bugs@NetBSD.org
Subject: SCSI getconfiguration requests have size limit on USB3 only but do not return errors
X-Send-Pr-Version: 3.95

>Number:         56109
>Category:       kern
>Synopsis:       SCSI getconfiguration requests have size limit on USB3 only but do not return errors
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          closed
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Apr 16 12:45:00 +0000 2021
>Closed-Date:    Tue Feb 01 14:22:12 +0000 2022
>Last-Modified:  Tue Feb 01 14:22:12 +0000 2022
>Originator:     Reinoud Zandijk
>Release:        NetBSD 9.99.81
>Organization:
NetBSD

>Environment:


System: NetBSD gorilla.13thmonkey.org 9.99.81 NetBSD 9.99.81 (GENERIC) #1: Fri Apr 16 09:17:54 CEST 2021 reinoud@gorilla.13thmonkey.org:/usr/tmp/obj/sys/arch/amd64/compile/GENERIC amd64
Architecture: x86_64
Machine: amd64
Sources from Apr 15th.

>Description:

Non bulk read/write SCSI data read calls are size limited on their return
buffer length and are not transfered correctly from a device over USB3 or on
USB2 when an USB3 hubs is in between if bigger than 0x200. This size limit is
not on USB2 only machines nor on ATAPI/SATA connected drives.

The problem manifested itself with the GET_CONFIGURATION MMC call for
CD/DVD/BD players/recorders that transfers data about settings and
capabilities of the drive in chunks. On USB2, the maximum size of 0xffff can
be specified. On USB3 its failing silently; when transfering more than 0x200
bytes at a time, the SCSI call does NOT return an error but the memory block
is not filled in either; it is left untouched effectively returning garbage
when the block is not cleared in advance.

When specifying a larger buffer than the drive has to offer, USB2 seems to
fill it in upto 0x200 but I haven't seen a drive giving more than 0x140 in
practice so I am not sure what would happen if it is bigger; it might just
truncate it to 0x200. ATAPI/SATA drives will normally transfer for the size
they have.

USB3 will transfer upto 0x200 fine but on bigger requests returns NO error and
is not touching the buffer at all.


>How-To-Repeat:
Plug in an USB CD/DVD recorder drive in an USB3 port and run the following
program and see that for requests bigger than 0x200 it shows this behavior but
when plugged in an USB2 only machine this size limit at least transfers upto
0x200.

--------------------------
/*
 * Test program to show issue with CD/DVD/BD player/recorder connected over
 * USB3 where connected over USB2 works as expected.
 *
 * Transfers with databuf_len > 0x200 fail on USB3 where they succeed on USB2.
 * Note it does NOT return an error and the memory is left untouched.
 */

#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <errno.h>
#include <strings.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <sys/scsiio.h>

#define SCSI_CMD_LEN  12
typedef unsigned char scsicmd[SCSI_CMD_LEN];

int
main(int argc, char **argv) {
	scsireq_t req;
	scsicmd	  cmd;
	uint8_t  *databuf;
	int fd;
	int databuf_len;

	if (argc != 3) {
		fprintf(stderr, "usage: scsi_issue drive size\n");
		return 1;
	}

	fd = open(argv[1], O_RDWR, 0);
	if (fd < 0) {
		fprintf(stderr, "can't open device %s : %s\n", argv[1], strerror(errno));
		return ENODEV;
	}

	databuf_len = atoi(argv[2]);
	if (databuf_len <= 0) {
		fprintf(stderr, "invalid size\n");
		return 1;
	}

	databuf = malloc(databuf_len);
	memset(databuf, 0xff, databuf_len);

	bzero(cmd, SCSI_CMD_LEN);
	cmd[0] = 0x46;			// get configuration
	cmd[1] = 0;			// all independent of current setting
	cmd[2] = 0;			// MSB last feature
	cmd[3] = 0;			// LSB last feature
	cmd[7] = databuf_len >> 8;	// MSB buffersize
	cmd[8] = databuf_len & 0xff;	// LSB buffersize
	cmd[9] = 0;			// control

	memset(&req, 0, sizeof(req));
	req.cmdlen   = 10;
	memcpy(req.cmd, cmd, req.cmdlen);
	req.databuf  = databuf;
	req.datalen  = databuf_len;
	req.timeout  = 30000;
	req.flags    = SCCMD_READ;
	req.senselen = 0;

	if (ioctl(fd, SCIOCCOMMAND, &req) == -1) {
		fprintf(stderr, "SCSI command failed : %s\n", strerror(errno));
		exit(1);
	}

	for (int i = 0; i < databuf_len; i++) {
		printf("%02x ", databuf[i]);
		if (i % 16 == 15) printf("\n");
	}
	printf("\n");
	return 0;
}
--------------------------


>Fix:
Adapt programs to use buffers less than 0x200 for each transfer.


>Release-Note:

>Audit-Trail:
From: Martin Husemann <martin@duskware.de>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/56109: SCSI getconfiguration requests have size limit on
 USB3 only but do not return errors
Date: Fri, 16 Apr 2021 14:58:50 +0200

 With how many drives have you tested this? Show at least dmesg of them.
 What caps do they offer?

 Martin

From: "Reinoud Zandijk" <reinoud@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/56109 CVS commit: src/sys/dev/scsipi
Date: Fri, 16 Apr 2021 12:58:54 +0000

 Module Name:	src
 Committed By:	reinoud
 Date:		Fri Apr 16 12:58:54 UTC 2021

 Modified Files:
 	src/sys/dev/scsipi: cd.c

 Log Message:
 Limit buffer size for device capabilities requests as a work-around for PR
 kern/56109.


 To generate a diff of this commit:
 cvs rdiff -u -r1.350 -r1.351 src/sys/dev/scsipi/cd.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

From: "Martin Husemann" <martin@netbsd.org>
To: gnats-bugs@gnats.NetBSD.org
Cc: 
Subject: PR/56109 CVS commit: [netbsd-9] src/sys/dev/scsipi
Date: Tue, 1 Feb 2022 11:41:29 +0000

 Module Name:	src
 Committed By:	martin
 Date:		Tue Feb  1 11:41:29 UTC 2022

 Modified Files:
 	src/sys/dev/scsipi [netbsd-9]: cd.c

 Log Message:
 Pull up following revision(s) (requested by reinoud in ticket #1421):

 	sys/dev/scsipi/cd.c: revision 1.351

 Limit buffer size for device capabilities requests as a work-around for PR
 kern/56109.


 To generate a diff of this commit:
 cvs rdiff -u -r1.342.4.2 -r1.342.4.3 src/sys/dev/scsipi/cd.c

 Please note that diffs are not public domain; they are subject to the
 copyright notices on the relevant files.

State-Changed-From-To: open->closed
State-Changed-By: reinoud@NetBSD.org
State-Changed-When: Tue, 01 Feb 2022 14:22:12 +0000
State-Changed-Why:
Fixed with revision 1.351 of sys/dev/scsipi/cd.c


>Unformatted:

NetBSD Home
NetBSD PR Database Search

(Contact us) $NetBSD: query-full-pr,v 1.46 2020/01/03 16:35:01 leot Exp $
$NetBSD: gnats_config.sh,v 1.9 2014/08/02 14:16:04 spz Exp $
Copyright © 1994-2020 The NetBSD Foundation, Inc. ALL RIGHTS RESERVED.