public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Matthew Dharm <mdharm-scsi@one-eyed-alien.net>
To: James Bottomley <James.Bottomley@steeleye.com>
Cc: Linus Torvalds <torvalds@transmeta.com>,
	USB Developers <linux-usb-devel@lists.sourceforge.net>,
	USB Storage List <usb-storage@one-eyed-alien.net>,
	Linux SCSI list <linux-scsi@vger.kernel.org>
Subject: Re: PATCH: exclude certain commands from emulated SCSI hosts
Date: Sat, 5 Apr 2003 11:27:59 -0800	[thread overview]
Message-ID: <20030405112759.B4320@one-eyed-alien.net> (raw)
In-Reply-To: <1049556643.1762.16.camel@mulgrave>; from James.Bottomley@steeleye.com on Sat, Apr 05, 2003 at 09:30:41AM -0600

[-- Attachment #1: Type: text/plain, Size: 5834 bytes --]

I don't think this will work.  I see two problems:

(1) You can't filter TEST_UNIT_READY (opcode 0).  Not a big deal, but a
theoretical problem.

(2) We need to be able to filter at the originator.  For example,
MODE_SENSE is perfectly fine to send to a CD-ROM, but not to a hard-disk.
We can't make that distinction with your code, unless we put the filtering
code not in queuecommand but in places like sd.c.... or we need to change
the filter to also take a device type.

Matt

On Sat, Apr 05, 2003 at 09:30:41AM -0600, James Bottomley wrote:
> On Mon, 2003-03-24 at 11:30, Matthew Dharm wrote:
> > On Mon, Mar 24, 2003 at 09:15:57AM -0600, James Bottomley wrote:
> > > OK, I can do this: A simple one with either a blacklist (reject these
> > > commands) or whitelist (only accept these commands) going by the first
> > > command byte OK?
> > 
> > Well, you need to go by more than the first command byte -- ex. INQUIRY is
> > okay, unless length != 36 or EVPD.
> > 
> > I think a blacklist is probably in order, but with a BIG COMMENT mentioning
> > that if someone adds new commands into the code paths they should at least
> > consider if they belong in the blacklist.
> 
> OK, try the attached.  There is no central blacklist, you must construct
> it on a per driver basis, so in the queuecommand of your driver you have
> a:
> 
> 	static struct scsi_cmd_filter filter =
> 		{ SCSI_FILTER_BLACKLIST ,
> 		  { MODE_SENSE, SCSI_FILTER_INQUIRY_NOT36, 0 } };
> 
> 	if(scsi_filter_cmd(SCp, &filter)) {
> 		SCp->scsi_done(SCp);
> 		return 0;
> 	}
> 
> to use the filter (I think, I've compiled but not tested it).
> 
> Let me know how it goes.
> 
> James
> 

> ===== drivers/scsi/scsi.h 1.68 vs edited =====
> --- 1.68/drivers/scsi/scsi.h	Mon Mar 24 11:23:37 2003
> +++ edited/drivers/scsi/scsi.h	Sat Apr  5 09:24:38 2003
> @@ -959,4 +959,39 @@
>  extern int scsi_sysfs_register(void);
>  extern void scsi_sysfs_unregister(void);
>  
> +struct scsi_cmd_filter {
> +	enum {
> +		SCSI_FILTER_WHITELIST,
> +		SCSI_FILTER_BLACKLIST
> +	} type;
> +	/* normal scsi commands are bytes, exceptions are words.  The format
> +	 * of the exceptions is:
> +	 *
> +	 * Byte 15: invert the specific condition
> +	 * Byte 14-12: Reserved
> +	 * Byte 11-8: command opcode (must be > 0)
> +	 * Byte 7-0: Command specific */
> +	unsigned short commands[];
> +};
> +
> +extern int scsi_filter_cmd(struct scsi_cmnd *, struct scsi_cmd_filter *);
> +
> +/* exception definitions for the filter */
> +#define SCSI_FILTER_INVERT		0x8000
> +
> +/* opcodes for the filter */
> +#define SCSI_FILTER_INQUIRY		0x0100
> +
> +/* useful filter commands */
> +#define SCSI_FILTER_INQUIRY_36		(SCSI_FILTER_INQUIRY | 36)
> +#define SCSI_FILTER_INQUIRY_NOT36	(SCSI_FILTER_INVERT | SCSI_FILTER_INQUIRY | 36)
> +
> +static inline unsigned short scsi_filter_opcode(unsigned short command) {
> +	return command & 0x7f00;
> +}
> +
> +static inline unsigned char scsi_filter_data(unsigned short command) {
> +	return (unsigned char)(command & 0x00ff);
> +}
> +
>  #endif /* _SCSI_H */
> ===== drivers/scsi/scsi_lib.c 1.75 vs edited =====
> --- 1.75/drivers/scsi/scsi_lib.c	Fri Mar 14 18:35:27 2003
> +++ edited/drivers/scsi/scsi_lib.c	Sat Apr  5 09:27:35 2003
> @@ -1375,3 +1375,71 @@
>  		kmem_cache_destroy(sgp->slab);
>  	}
>  }
> +
> +static inline int scsi_filter_exceptions(struct scsi_cmnd *cmd,
> +					 unsigned short command)
> +{
> +	int found = 0;
> +
> +	/* specials begin at 0x100 */
> +	if(command < 0x100)
> +		return 0;
> +
> +	switch(scsi_filter_opcode(command)) {
> +
> +	case SCSI_FILTER_INQUIRY:
> +		if(cmd->cmnd[0] != INQUIRY)
> +			return 0;
> +		/* does the transfer length match the data */
> +		found = (cmd->cmnd[4] == scsi_filter_data(command));
> +		/* now check for inversion */
> +		if(command & SCSI_FILTER_INVERT)
> +			found = !found;
> +		return found;
> +	default:
> +		/* unrecognized filter */
> +		return 0;
> +	}
> +}
> +
> +/**
> + * scsi_filter_cmd - Filter a given command against a list
> + * @cmd: command to be filtered.
> + * @filter: pointer to the filter containing the type (black/white list) and
> + * zero terminated list of commands to filter against (first byte only).
> + *
> + * Returns 0 if the filter passed successfully and the driver can continue
> + * processing the command or 1 if the filter failed and the command should
> + * be finished (via ->scsi_done).  In the latter case, the command will have
> + * the sense fields filled in indicating the correct sense for an illegal
> + * request.
> + **/
> +int scsi_filter_cmd(struct scsi_cmnd *cmd, struct scsi_cmd_filter *filter)
> +{
> +	int found = 0;
> +	unsigned short *command;
> +
> +	for(command = filter->commands; *command; command++) {
> +		found = scsi_filter_exceptions(cmd, *command);
> +		found += (cmd->cmnd[0] != *command);
> +		if(found)
> +			break;
> +	}
> +
> +	if((found && filter->type == SCSI_FILTER_WHITELIST) ||
> +	   (!found && filter->type == SCSI_FILTER_BLACKLIST))
> +		return 0;
> +
> +	/* fill in the Check Condition/Illegal request */
> +	cmd->result = SAM_STAT_CHECK_CONDITION;
> +	memset(cmd->sense_buffer, '\0', sizeof(cmd->sense_buffer));
> +	cmd->sense_buffer[0] = 0xF0; /* valid, response code 0x70 */
> +	cmd->sense_buffer[2] = ILLEGAL_REQUEST;
> +
> +	/* ASC 0x20, ASCQ 0x00: Invalid command operation code */
> +	cmd->sense_buffer[12] = 0x20;
> +	cmd->sense_buffer[13] = 0x00;
> +
> +	return 1;
> +}
> +	


-- 
Matthew Dharm                              Home: mdharm-usb@one-eyed-alien.net 
Maintainer, Linux USB Mass Storage Driver

IT KEEPS ASKING ME WHERE I WANT TO GO TODAY! I DONT WANT TO GO ANYWHERE!
					-- Greg
User Friendly, 11/28/97

[-- Attachment #2: Type: application/pgp-signature, Size: 232 bytes --]

  reply	other threads:[~2003-04-05 19:16 UTC|newest]

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20030322193046.A17056@one-eyed-alien.net>
     [not found] ` <20030322193149.B17056@one-eyed-alien.net>
2003-03-23  3:37   ` PATCH: exclude certain commands from emulated SCSI hosts Matthew Dharm
2003-03-23  4:09     ` Linus Torvalds
2003-03-23  7:31       ` Matthew Dharm
2003-03-23  7:39         ` Linus Torvalds
2003-03-23 18:13           ` [usb-storage] " Matthew Dharm
2003-03-24  1:05             ` Douglas Gilbert
2003-03-24  1:26         ` James Bottomley
2003-03-24  1:37           ` Matthew Dharm
2003-03-24  1:39             ` James Bottomley
2003-03-24  7:04               ` Matthew Dharm
2003-03-24 15:15                 ` James Bottomley
2003-03-24 16:29                   ` Linus Torvalds
2003-03-24 16:43                     ` James Bottomley
2003-03-24 16:52                     ` Jens Axboe
2003-03-24 16:56                       ` James Bottomley
2003-03-24 17:30                   ` Matthew Dharm
2003-04-05 15:30                     ` James Bottomley
2003-04-05 19:27                       ` Matthew Dharm [this message]
2003-04-05 19:45                         ` James Bottomley
2003-04-05 19:55                           ` Matthew Dharm
2003-04-05 20:08                             ` James Bottomley
2003-04-06  0:20                               ` Matthew Dharm
2003-04-06  0:22                           ` Matthew Dharm
2003-04-06 15:39                             ` James Bottomley
2003-04-07 22:33                       ` Patrick Mansfield
2003-04-07 23:14                         ` James Bottomley
2003-04-08  0:51                           ` Patrick Mansfield
2003-04-20 21:33                       ` Matthew Dharm
2003-04-20 21:35                         ` Matthew Dharm
2003-04-21 16:20                           ` James Bottomley
2003-04-21 17:02                             ` Matthew Dharm
2003-04-21 16:28                         ` James Bottomley
2003-04-21 17:01                           ` Matthew Dharm
2003-04-21 19:23                             ` James Bottomley
2003-04-21 19:35                               ` Matthew Dharm
2003-04-21 21:27                                 ` James Bottomley
2003-04-21 23:37                                   ` Matthew Dharm
2003-04-21 21:28                                 ` Patrick Mansfield
2003-04-21 23:45                                   ` Matthew Dharm
2003-03-24  1:58             ` Linus Torvalds
2003-03-24  6:58               ` Matthew Dharm
2003-04-22 17:37 [usb-storage] " James Bottomley
2003-04-22 18:13 ` Alan Stern
  -- strict thread matches above, loose matches on Subject: below --
2003-04-22 19:30 Andries.Brouwer
2003-04-22 19:41 ` James Bottomley
2003-04-22 19:50 Andries.Brouwer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20030405112759.B4320@one-eyed-alien.net \
    --to=mdharm-scsi@one-eyed-alien.net \
    --cc=James.Bottomley@steeleye.com \
    --cc=linux-scsi@vger.kernel.org \
    --cc=linux-usb-devel@lists.sourceforge.net \
    --cc=torvalds@transmeta.com \
    --cc=usb-storage@one-eyed-alien.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox